至少有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;

    }
}
发布了149 篇原创文章 · 获赞 137 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/zhang_ye_ye/article/details/99350523