1239. 串联字符串的最大长度 力扣(中等) 回溯,减枝,不敢写,怕超时
1239. 串联字符串的最大长度
给定一个字符串数组 arr,字符串 s 是将 arr 某一子序列字符串连接所得的字符串,如果 s 中的每一个字符都只出现过一次,那么它就是一个可行解。
请返回所有可行解 s 中最长长度。
示例 1:
输入:arr = ["un","iq","ue"]
输出:4
解释:所有可能的串联组合是 "","un","iq","ue","uniq" 和 "ique",最大长度为 4。
题解:
2^16回溯情况,加一点点减枝,过了!!!!
回溯+减枝
如果两个字符串拼在一起,长度>26,说明肯定重复了,不用选了
特殊情况,如果字符串本来就自带重复,这个需要先筛选掉,我给忽略了!!
官方题解中用位运算,来快速判断两个字符串是否含有相同字母!会比两个循环快点!!
代码:
class Solution { public: int res; int n; void dfs(int k,string s,vector<string> arr) { if(k>=n) { // res=max(res,s.length() ); // 怎么max函数不能用吗??? if(res<s.length()) res=s.length(); return; } if(arr[k].length()+s.length()>26) dfs(k+1,s,arr); else { bool flag=1; // 判断arr[k]是不是自带重复 bool vis[30]; memset(vis,0,sizeof(vis)); for(auto i:arr[k]) if (vis[i-'a']==1) {flag=0; break;} else vis[i-'a']=1; if (flag) for(auto i:s) // 第k个字符串arr[k]和现在的字符串s的有没有重叠字母 { for(auto j:arr[k]) if (i==j) { flag=0; break;} if(!flag) break; } if(flag) dfs(k+1,s+arr[k],arr); // 选择 dfs(k+1,s,arr); // 不选 } } int maxLength(vector<string>& arr) { // 首先发现有16个字符串,dfs可能超时,所以不敢尝试 res=0; n=arr.size(); // 特殊情况:arr中一个字符串自带重复,不能选择 dfs(0,"",arr); return res; } };
虽然只是小小优化,但是也没有超时:
执行用时:124 ms, 在所有 C++ 提交中击败了16.23%的用户
内存消耗:171 MB, 在所有 C++ 提交中击败了4.99%的用户