【码不停题3.7】每一字符出现次数都不少于 k的最长子串 T

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

示例 1:

输入:
s = “aaabb”, k = 3

输出:
3

最长子串为 “aaa” ,其中 ‘a’ 重复了 3 次。
示例 2:

输入:
s = “ababbc”, k = 2

输出:
5

最长子串为 “ababb” ,其中 ‘a’ 重复了 2 次, ‘b’ 重复了 3 次。

python3

class Solution:
    def longestSubstring(self, s, k):
        """
        :type s: str
        :type k: int
        :rtype: int
        """
        for i in set(s):
            if s.count(i) < k: # 找出不满足k次的字母
                return max(self.longestSubstring(m, k) for m in s.split(i)) # 将其作为分割点进行分治
        return len(s)

C++

class Solution {
public:
    int longestSubstring(string s, int k) {
        int n = s.size(), max_idx = 0, res = 0;
        int m[128] = {0};
        bool ok = true;
        // 先全部count
        for (char c : s) ++m[c];
      	
        for (int i = 0; i < n; ++i) {
            if (m[s[i]] < k) {
                res = max(res, longestSubstring(s.substr(max_idx, i - max_idx), k));// s.substr第二个参数是len
                ok = false;
                max_idx = i + 1;
            }
        }
        return ok ? n : max(res, longestSubstring(s.substr(max_idx, n - max_idx), k));
    }
};

解法2

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循环算出从i开始可以往后的最长的位置填在max_idx
            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;
    }
};

猜你喜欢

转载自blog.csdn.net/MmmTHU/article/details/88309088