至少有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、將所有的字母數目做一統計
2、有左右兩個指針,如果對應的字母數量小於k,向內移動指針
3、找到左右兩個指針中間數量小於k的字母,從此處分開,遞歸
4、結束條件:當剩餘字符的數量小於k,返回0

代碼實現

package solution;


class Solution {
    public static void main(String[] args) {
        Solution solution=new Solution();
        int i=solution.longestSubstring("ababbc",2);
        System.out.println(i);
    }
    public int longestSubstring(String s, int k) {
        return part(s.toCharArray(),k,0,s.length()-1);
    }
    public int part(char[] arr,int k,int left,int right){
        //所剩字母數量小於k,說明不滿足條件
        if(right-left+1<k){
            return 0;
        }
        //記錄字符數量的數組
        int[] counts=new int[26];
        //統計數量
        for(int i=left;i<=right;i++){
            counts[arr[i]-'a']=counts[arr[i]-'a']+1;
        }
        //向右移動指針
        while (right-left+1>=k&&counts[arr[left]-'a']<k){
            left++;
        }
        //向左移動指針
        while (right-left+1>=k&&counts[arr[right]-'a']<k){
            right--;
        }
        if(right-left+1<k){
            return 0;
        }
        for (int i=left;i<=right;i++){
            if(counts[arr[i]-'a']<k){
                //如果中間還有不滿足條件的字符,遞歸
                return Math.max(part(arr,k,left,i-1),part(arr,k,i+1,right));
            }
        }
        return right-left+1;

    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章