1.Description
给你一个字符串 s 和一个整数 k ,请你找出 s 中的最长子串, 要求该子串中的每一字符出现次数都不少于 k 。返回这一子串的长度。
2.Example
输入:s = "aaabb", k = 3
输出:3
解释:最长子串为 "aaa" ,其中 'a' 重复了 3 次。
输入:s = "ababbc", k = 2
输出:5
解释:最长子串为 "ababb" ,其中 'a' 重复了 2 次, 'b' 重复了 3 次。
3.Solution
2.滑动窗口
直接在字符串s上使用滑动窗口是不行的,根据一个窗口内包含几个不同的字母在s上进行滑动窗口才行。
1.右端点往右移动必然会导致字符类型数量增加(或不变)
2.左端点往右移动必然会导致字符类型数量减少(或不变)
public int longestSubstring(String s, int k) {
int max = 0;
int[] chs = new int[26];
for(int t=1;t<=26;t++) {
//将chs数组归零
for(int i=0;i<26;i++) {
chs[i] = 0;
}
//less代表有多少个出现次数小于k的字母,tot代表一共有多少个不同的字母
for(int i=0,j=0,less=0,tot=0;j<s.length();j++) {
int ch = s.charAt(j)-'a';
chs[ch]++;
//如果加一之后是1的话,说明进来一个新的字母,less++,tot++
if(chs[ch]==1) {
less++;
tot++;
}
//加一之后是k的话,说明出现次数等于k了,less--
if(chs[ch]==k) {
less--;
}
//j往后移动一位,如果从右边加进来了一个新的没出现过的字母的话,tot就大于t了,需要从左边开始去掉一种字母,使tot等于t
while(tot>t) {
int c = s.charAt(i++)-'a';//c保存i位置的字母,然后i++
chs[c]--;
if(chs[c]==0) {
less--;
tot--;
}
if(chs[c]==k-1) {
less++;
}
}
if(less==0) {
max = Math.max(max, j-i+1);
}
}
}
return max;
}