LeetCode c++ 至少有K个重复字符的最长子串

找到给定字符串(由小写字符组成)中的最长子串 T , 要求 T 中的每一字符出现次数都不少于 k 。输出 T 的长度。

示例 1:

输入:
s = "aaabb", k = 3

输出:
3

最长子串为 "aaa" ,其中 'a' 重复了 3 次。
示例 2:

输入:
s = "ababbc", k = 2

输出:
5

最长子串为 "ababb" ,其中 'a' 重复了 2 次, 'b' 重复了 3 次。
1.emmm...,其实我没搞懂这个思路。。。

class Solution {
public:
    int longestSubstring(string s, int k) {
        int res = 0, i = 0, n = s.size();
        while (i + k <= n) {
            int m[26] = {0}, mask = 0, max_idx = i;
            for (int j = i; j < n; ++j) {
                int t = s[j] - 'a';
                ++m[t];
                if (m[t] < k) mask |= (1 << t);
                else mask &= (~(1 << t));
                if (mask == 0) {
                    res = max(res, j - i + 1);
                    max_idx = j;
                }
            }
            i = max_idx + 1;
        }
        return res;
    }
};

2.注:以下需要注意的是 nums[s[start] - 'a'] < k,中间之前忘记s。。。,并且对于&&、||等符号两侧最好加括号,尤其是不肯定符号优先级顺序的时候。

while ((end - start + 1 >= k) && (nums[s[start] - 'a'] < k)) start++;
while ((end - start + 1 >= k) && (nums[s[end] - 'a'] < k)) end--;

还要注意:这里i的范围为[start,end]!!

for (int i = start; i <= end; ++i){
    nums[s[i] - 'a']++;
}
//分治:
//设置这样的递归函数: 统计当前范围内的字符频数, 然后先左后右截断多余的出现频数小于k的字符, 若截断至字符长度小于k则直接返回0
//   否则: 对中间任意位置进行判断, 如果中间某个字符出现频数小于k, 则截断它, return 左右子串的结果最大值
//   如果中间字符频数都大于等于k, 则返回当前字符串长度

class Solution {
private:
    int recu(const string& s, int start, int end, int k)
    {
        if (end - start + 1 < k) return 0;
        //统计频数
        vector nums(26, 0);
        for (int i = start; i <= end; ++i)
        {
            nums[s[i] - 'a']++;
        }

        //截断
        while ((end - start + 1 >= k) && (nums[s[start] - 'a'] < k)) start++;
        while ((end - start + 1 >= k) && (nums[s[end] - 'a'] < k)) end--;
        if (end - start + 1 < k) return 0;

        //中间判断
        for (int i = start + 1; i < end; ++i)
        {
            if (nums[s[i] - 'a'] < k) return max(recu(s, start, i - 1, k), recu(s, i + 1, end, k));
        }
        return end - start + 1;
    }

public:
    int longestSubstring(string s, int k) {
        if ((k == 0) || (s.size() < k)) return 0;
        else return recu(s, 0, s.size() - 1, k);
    }
};

你可能感兴趣的:(LeetCode c++ 至少有K个重复字符的最长子串)