395. 至少有 K 个重复字符的最长子串

给你一个字符串 s 和一个整数 k ,请你找出 s 中的最长子串, 要求该子串中的每一字符出现次数都不少于 k 。返回这一子串的长度。

示例 1:

输入:s = "aaabb", k = 3
输出:3
解释:最长子串为 "aaa" ,其中 'a' 重复了 3 次。
示例 2:

输入:s = "ababbc", k = 2
输出:5
解释:最长子串为 "ababb" ,其中 'a' 重复了 2 次, 'b' 重复了 3 次。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-with-at-least-k-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分治

class Solution {

    private int dfs(String s, int start, int end, int k) {
        if (end - start + 1 < k) {
            return 0;
        }
        int[] cnt = new int[26];
        for (int i = start; i <= end; ++i) {
            cnt[s.charAt(i) - 'a']++;
        }
        char split = 0;
        for (int i = 0; i < 26; ++i) {
            if (cnt[i] != 0 && cnt[i] < k) {
                split = (char) (i + 'a');
            }
        }
        if (split == 0) {
            return end - start + 1;
        }
        int ans = 0;
        int left = start, right;
        while (left <= end) {
            while (left <= end && s.charAt(left) == split) {
                left++;
            }
            right = left;
            while (right <= end && s.charAt(right) != split) {
                right++;
            }
            ans = Math.max(ans, dfs(s, left, right - 1, k));
            left = right;
        }
        return ans;
    }

    public int longestSubstring(String s, int k) {
        return dfs(s, 0, s.length() - 1, k);
    }
}

滑动窗口

class Solution {
    public int longestSubstring(String s, int k) {
        int ans = 0;
        for (int i = 1; i <= 26; ++i) {
            int[] cnt = new int[26];
            int total = 0, less = 0;
            int left = 0, right = 0;
            while (right < s.length()) {
                cnt[s.charAt(right) - 'a']++;
                if (cnt[s.charAt(right) - 'a'] == 1) {
                    total++;
                    less++;
                }
                if (cnt[s.charAt(right) - 'a'] == k) {
                    less--;
                }
                while (total > i) {
                    cnt[s.charAt(left) - 'a']--;
                    if (cnt[s.charAt(left) - 'a'] == k - 1) {
                        less++;
                    }
                    if (cnt[s.charAt(left) - 'a'] == 0) {
                        less--;
                        total--;
                    }
                    left++;
                }
                if (less == 0) {
                    ans = Math.max(ans, right - left + 1);
                }
                right++;
            }
        }
        return ans;
    }
}
posted @ 2021-12-28 16:07  Tianyiya  阅读(31)  评论(0)    收藏  举报