Longest Substring with At Least K Repeating Characters(bit mask)

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;
    }
};

猜你喜欢

转载自blog.csdn.net/futangxiang4793/article/details/88901848