[刷題]Leetcode 395. 至少有K個重複字符的最長子串

同窗去面抖音被問到了這道題,趕忙去看了一下 發現本身也不會
哈哈哈哈哈,so.. 記個筆記 便於複習數組

題目描述code

找到給定字符串(由小寫字符組成)中的最長子串 T , 
要求 T 中的每一字符出現次數都很多於 k 。
輸出 T 的長度。

示例 1:字符串

輸入:
s = "aaabb", k = 3
輸出:
3
最長子串爲 "aaa" ,其中 'a' 重複了 3 次。

示例 2:string

輸入:
s = "ababbc", k = 2
輸出:
5
最長子串爲 "ababb" ,其中 'a' 重複了 2 次, 'b' 重複了 3 次。

這道題的意思就是找一個子串,這個子串裏的全部字符的出現頻率都不低於K,找出最長的這樣的子串
還有題目沒有說太明確,其實由小寫字符組成就是說只有‘a-z‘的小寫字母,這樣咱們就能夠方便地用數組來統計啦~io

思路:
若是不知足條件的字符出如今了字符串兩邊好說,咱們只須要把兩邊不知足條件的字符去掉
麻煩的是 字符可能出如今中間 因而考慮用分治法去解決這個問題 把大問題劃分爲幾個小問題, 若是字符出如今了中間 咱們就把字符串從這個字符這裏劈開,左邊去求解這個問題,右邊也去求解這個問題,最後取左右倆邊結果的最大值就OK了
關於某個字符是否知足條件,咱們只須要提早遍歷一遍字符串,統計一下就OK了~class

代碼以下:遍歷

class Solution {
    public int longestSubstring(String s, int k) {
        if(s==null) return 0;
        if(s.length()==0) return 0;
        if(k<=1) return s.length();
        return count(s, k, 0, s.length()-1);
        

    }

    public int count(String s, int k, int left , int right){
        if(right-left+1<k) return 0;
        int[] cnt = new int[26];
        for(int i=left;i<=right;i++){
            ++cnt[s.charAt(i)-'a'];
        }
        // 去除左右兩邊不知足條件的字符
        while(right-left+1>=k && cnt[s.charAt(left)-'a']<k){
            left++;
        }

        while(right-left+1>=k && cnt[s.charAt(right)-'a']<k){
            right--;
        }
        if(right-left+1<k) return 0;
        
        // 劈開分治
        for(int i =left;i<=right;i++){
            // 只須要劈開一次就能夠返回了,
            // 由於即便右邊還有不知足條件的字符,
            // 也會在其子階段求解獲得了
            if(cnt[s.charAt(i)-'a']<k){
                return Math.max(count(s, k, left, i-1), count(s, k, i+1, right));
            }
        }
        return right-left+1;

    }

}
相關文章
相關標籤/搜索