题干信息
IDEA
方法1:滑动窗口
- 这道题与以往的题目不同是(独特之处),将滑动窗口的条件相对松弛一点。先找出所有的"候选答案",再从"候选答案"中找出最优解。
- 将原始问题的解空间进行划分,在每一个可行解空间中求得可能的最优解。所有的最优解再求最优解即为最优解。
- 对于这道题,使用串中可能出现的字符的数量进行划分。
- 对于可能包含的字符种类讨论,分别求可行解。
class Solution {
public int longestSubstring(String s, int k) {
int len_s = s.length();
int ret = 0;
for(int t = 1;t<=26;t++) //统计每一种字符的种类
{
//对于每一个r的取值,统计每一个最小的使得字符种类为k的取值
//显然l只可能往右侧移动
int l = 0;
int[] cnt = new int[26]; //每一个字符出现的次数
int tot = 0; //当前窗口总的字符种类个数
int restrict = 0; //不满足
for(int r = 0;r < len_s;r++)
{
cnt[s.charAt(r) - 'a'] ++;
if(cnt[s.charAt(r) - 'a'] == 1) //一定是从0变为1的
{
tot++; //当前窗口中字符的种类数加1
restrict++; //不满足约束条件的字符种类数加1
}
if(cnt[s.charAt(r) - 'a'] == k)
{
restrict--; //不满足约束条件的字符种类数减1
}
while(tot > t)
{
if(cnt[s.charAt(l) - 'a'] == k)
restrict++;
if(cnt[s.charAt(l) - 'a'] == 1)
{
tot--; //窗口中的总字符数减少
restrict--; //窗口中不满足约束条件的字符种类数减少
}
cnt[s.charAt(l) - 'a']--;
l++;
}
if(restrict == 0)
ret = Math.max(ret,r - l + 1);
}
}
return ret;
}
}