其他分享
首页 > 其他分享> > 1239. 串联字符串的最大长度 力扣(中等) 回溯,减枝,不敢写,怕超时

1239. 串联字符串的最大长度 力扣(中等) 回溯,减枝,不敢写,怕超时

作者:互联网

1239. 串联字符串的最大长度

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

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

 

示例 1:

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

题解:

2^16回溯情况,加一点点减枝,过了!!!!

回溯+减枝

如果两个字符串拼在一起,长度>26,说明肯定重复了,不用选了

特殊情况,如果字符串本来就自带重复,这个需要先筛选掉,我给忽略了!!

官方题解中用位运算,来快速判断两个字符串是否含有相同字母!会比两个循环快点!!

https://leetcode-cn.com/problems/maximum-length-of-a-concatenated-string-with-unique-characters/solution/chuan-lian-zi-fu-chuan-de-zui-da-chang-d-g6gk/

代码:

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%的用户

标签:arr,res,flag,1239,dfs,力扣,vis,减枝,字符串
来源: https://www.cnblogs.com/stepping/p/15113538.html