Find the length of the longest substring T of a given string (consists of lowercase letters only) such that every character in T appears no less than k times.
Example 1:
Input: s = "aaabb", k = 3 Output: 3 The longest substring is "aaa", as 'a' is repeated 3 times.
/* 找到一个子串 每个字符出现次数都不少于k次
*
* 方法 设起始位置i, 每次从i遍历到结尾, 一边检查当前是否满足要求 复杂度O(n^3)
*
* 优化1 检查: 设立map记录字符出现次数 用bitmask(int 有32位 可以表示26个bit)
* 如果不用mask每次都要遍历map
*
* mask 每一位上的值 由对应元素出现的次数决定 >= k 置为0,否则为1
* z y x... d c b a
* 0 0 0 1 0 1 0 当mask值为0时 显然所有bit也为0 这样就不用遍历map
*
* 优化2:由于输出的是最大长度 当前结果可能满足但不是最大长度 下次跳到的位置是当前满足的起始位置的下一个位置
*
* 位操作: a | 0001000 把对应位置1
* a & 1110111 把0所在位置置0
* */
class Solution {
public:
int longestSubstring(string s, int k) {
int len=s.length(), i=0, maxlen=0;
while(i+k<=len){
int mask=0, m[26]={0}, maxidx=i;
for(int j=i;j<len;j++){
int t = s[j]-'a';
++m[t];
if(m[t]<k) mask |= (1<<t);// 把不满足的位置1 1<<t 得到000010000 1的位置即是t在map中的位置
else mask &= ~(1<<t); // 把t所在的位置置0
if(mask == 0){// 不能直接break 向后继续遍历可能还会增长
maxlen = max(maxlen, j-i+1);
maxidx = j;
}
}
i = maxidx + 1; //
}
return maxlen;
}
};