其他分享
首页 > 其他分享> > 【LeetCode】395. 至少有 K 个重复字符的最长子串

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

作者:互联网

题目链接:https://leetcode-cn.com/problems/longest-substring-with-at-least-k-repeating-characters/

本题使用分治思想解决

(也可以使用滑动窗口的思想解决,但是我不会)

首先对于整个字符串,如果某个子串包含了【在字符串中出现次数少于k】的字符,那么根据题目定义,这个子串就不符合要求,因此,可以根据这些字符的位置,将整个字符串分割为多个子字符串,在这些子字符串中递归搜索符合要求的其子串,然后,在这些符合要求的子串中获取最大的一个,得出答案即可。

代码(Java)

class Solution {
    /*
     * L: 当前要处理的字符串的左端
     * R: 当前要处理的字符串的右端
     */
    public int sovle (String s, int k, int L, int R) {
        // 当L>R时,无法形成字符串,直接返回0
        if (L > R) return 0 ;
        // freq 频率数组,用于记录当前字符串每个字符出现的频率
        int[] freq = new int[26] ;
        for (int i = L;i <= R;i++) {
            freq[s.charAt(i) - 'a'] ++ ;
        }
        // 根据出现次数少于k的字符分割成多个子字符串
        int start = L ;
        int ans = 0 ;
        for (int i = L;i <= R;i++) {
            if (freq[s.charAt(i) - 'a'] < k && freq[s.charAt(i) - 'a'] != 0) {
                ans = Math.max(ans, sovle(s, k, start, i - 1)) ;
                start = i + 1 ;
             }
        }
        // 如果start等于L,那么说明当前的字符串中,每个字符出现次数都不小于k
        // 那么直接返回当前字符串长度即可
        if (start == L) return R - L + 1 ;
        // 如果start 不等于R + 1,说明最后一个字符出现次数不小于k
        // 在循环中,就会把最后一段漏掉
        // 所以这里需要特殊处理
        if (start != R + 1) {
            ans = Math.max(ans, sovle(s, k, start, R)) ;
        }
        return ans ;
    }
    public int longestSubstring(String s, int k) {
        int n = s.length() ;
        if (n == 0) return 0 ;
        return sovle(s, k, 0, s.length() - 1) ;
    }
}

标签:子串,字符,int,符合要求,395,字符串,freq,LeetCode
来源: https://www.cnblogs.com/Suans/p/14455747.html