虫虫首页| 资源下载| 资源专辑| 精品软件
登录| 注册

您现在的位置是:首页 > 技术阅读 >  每日一题1239:串联字符串的最大长度

每日一题1239:串联字符串的最大长度

时间:2024-02-14

给定一个字符串数组 arr,字符串 s 是将 arr 某一子序列字符串连接所得的字符串,如果 s 中的每一个字符都只出现过一次,那么它就是一个可行解。

请返回所有可行解 s 中最长长度。

示例1

输入:arr = ["un","iq","ue"]
输出:4
解释:所有可能的串联组合是 "","un","iq","ue","uniq" 和 "ique",最大长度为 4。

示例2

输入:arr = ["cha","r","act","ers"]
输出:6
解释:可能的解答有 "chaers" 和 "acters"。

示例3

输入:arr = ["abcdefghijklmnopqrstuvwxyz"]
输出:26

提示

  • 1 <= arr.length <= 16

  • 1 <= arr[i].length <= 26

  • arr[i] 中只含有小写英文字母

分析

这是一道回溯题,可以从头到尾遍历,维护一个当前选择的字符串字符的一个map,由于只有26个字符,所以这个map可以使用int的二进制位移方式代替,两种情况,选择当前字符串还是不选择当前字符串,如果不选择当前字符串,那返回值就等于从下一个节点开始计算的结果,如果选择当前字符串并且当前字符串符合可行解s的条件,那还需要更新map,结果为更新map后下一个节点计算后的值+当前字符串的长度,最后取两个分支(选择还是不选择)较大的值作为函数返回值。

代码

class Solution {
public:
   int a = 0;
   bool UniqueWhenAddStr(string &str) {
       for (auto c : str) {
           if (a & (1 << (c-'a'))) {
               return false;
           }
       }
       return true;
   }

   void AddStr(string &str) {
       for (auto c : str) {
           a = a | (1 << (c-'a'));
       }
   }

   void RemoveStr(string &str) {
       for (auto c : str) {
           a = a ^ (1 << (c-'a'));
       }
   }

   bool uniqueStr(string &str) {
       int b = 0;
       for (auto c : str) {
           if (b & (1 << (c-'a'))) {
               return false;
           } else {
               b = b | (1 << (c-'a'));
           }
       }
       return true;
   }

   int dfs(vector<string> &arr, int index) {
       if (arr.size() == index) return 0;
       int value = dfs(arr, index+1);
       if (uniqueStr(arr[index]) && UniqueWhenAddStr(arr[index])) {
           AddStr(arr[index]);
           int k = dfs(arr, index+1) + arr[index].size();
           int tem = std::max(k, value);
           RemoveStr(arr[index]);
           return tem;
       }
       return value;
   }

   int maxLength(vector<string>& arr) {
       return dfs(arr, 0);
   }
};
更多精彩推荐,请关注我们


代码精进之路


  代码精进之路,我们一起成长!