其他分享
首页 > 其他分享> > leetcode 395 至少有K个重复字符的最长子串

leetcode 395 至少有K个重复字符的最长子串

作者:互联网

初始想到的方法是通过哈希的方式统计每个字母出现的频率,其中出现过的并且出现次数小于k的字符,就可以作为下一次递归的分界依据。而若是频率统计中所有出现的字符的次数都大于k,则认为这一子串是符合要求的,就返回当前子串长度至上一级中。贴代码

 1 class Solution {
 2 public:
 3     int longestSubstring(string s, int k) 
 4     {
 5         return dfs(s,0,s.length()-1,k);
 6     }
 7     int dfs(string& s,int l,int r,int k)
 8     {
 9         //cout<<l<<r<<endl;
10         if(r-l+1<k)
11         return 0;
12         int maxSize = 0;
13         vector<int> ch(27,0);
14         for(int i = l ; i <= r ; i++)
15         ch[s[i]-'a']++;
16         vector<int> pos;
17         for(int i = l; i <= r ; i++)
18         {
19             //如果该字符出现次数小于要求,则即为分界线
20             if(ch[s[i]-'a']<k && ch[s[i]-'a']>0)
21             pos.push_back(i);
22         }
23         if(!pos.size())
24         return r-l+1;
25         //cout<<ch[0]<<endl;
26         pos.push_back(r+1);
27         int pos1 = -1;
28         for(int i = 0 ; i < pos.size() ; i++)
29         {
30             int pos2 = pos[i];
31             int t = dfs(s,pos1+1,pos2-1,k);
32             if(t>maxSize)
33             maxSize = t;
34             pos1 = pos2;
35         }
36         return maxSize;
37     }
38 };

还有一种方法,就是滑动窗口,而滑动窗口的大小是窗口内部不同的字符种类。维护一个记录所有字符元素频率的数组,同时维护当前窗口中字符种类数与出现频率小于k的字符种类数。基本的循环为右边界向右移一位,将该字符对应的数组元素加一,同时调整chnum和lessk。若该数为新字符,则chnum++,lessK加加,若该数的频率到达K,则lessK--。然后判断当前窗口中字符种类数,若是大于目标种类数,则不断弹出左边界的元素,直到当前窗口中字符种类数等于目标种类数。并判断当前lessK是否为0,若是0,则代表当前窗口内的可以,则计算长度。贴代码

 1 class Solution {
 2 public:
 3     int longestSubstring(string s, int k) 
 4     {
 5         int res = 0;
 6         int t = 1;
 7         int n = s.length();
 8         for(t = 1 ; t <= 26 ; t++)
 9         {
10             int chNum = 0;
11             int lessK = 0;
12             vector<int> countCh(26,0);
13             //t为字符种类
14             int l = 0;
15             int r = 0;
16             while(r<n)
17             {
18                 countCh[s[r]-'a']++;
19                 if(countCh[s[r]-'a'] == 1)
20                 {
21                     chNum++;
22                     lessK++;
23                 }
24                 if(countCh[s[r]-'a'] == k)
25                 lessK--;
26                 //如果当前字符种类大于预设种类
27                 while(chNum>t)
28                 {
29                     countCh[s[l]-'a']--;
30                     if(countCh[s[l]-'a'] == 0)
31                     {
32                         chNum--;
33                         lessK--;
34                     }
35                     if(countCh[s[l]-'a'] == k-1)
36                     lessK++;
37                     l++;
38                 }
39                 if(lessK == 0)
40                 res = max(res,r-l+1);
41                 r++;
42             }
43         } 
44         return res;  
45     }
46 };

 

标签:子串,字符,窗口,lessK,int,395,return,leetcode,种类
来源: https://www.cnblogs.com/zhaohhhh/p/15535281.html