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

在这里插入图片描述
今天做的最难的一道题(菜),一开始想要滑动窗口,不过估计做不出。所以用了递归分治,每次判断该字符串的字符是否都大于k次,就要每次都开一个哈希表,用数组记录就行。
用一个i遍历字符串,用while,记得判断越界操作,直到找到第一个小于k的或者越界就退出。如果是因为越界退出的,证明s中没有小于k的,返回整个s。
如果不是,证明s[i]这个字符出现次数小于k,我们计算它左边的复合要求的子串长度,用s.substr(0,i)即可。此时因为s[i]是不符合要求的,而s[i]又是重复出现的,我们用while跳过这些小于k次,退出循环时s[i]是复合要求的,也就是求右边的符合子串的长度,用s.substr(i)即可,会自动复制到最后一位,然后返回max(l,r)即可

class Solution {
public:
    int longestSubstring(string s, int k) {
        //滑动窗口中的每一个字符的出现次数都不小于k
        //要求的是符合要求的最长子串,不是最短,所以left不用收缩
        //可以考虑分治,找出哪个字母的出现次数小于k,就去它的左右找
        if(k <= 1) return s.length();
        if(s.length() < k) return 0;

        int hash[26] = {0};
        for(char c : s){
            hash[c-'a']++;
        }

        //然后找到s中第一个出现次数小于k的,去它的左右两边找
        int i = 0;
        while(i < s.length() && hash[s[i]-'a'] >= k) i++;
        //此时i可能走到头,也可能碰到了出现次数小于k的字符
        if(i == s.length()) return s.length();

        //substr有两个重载,一个参数的是从这个参数复制到尾,两个参数的是从第一个参数,复制第二个参数个数的字符
        int l = longestSubstring(s.substr(0,i),k);
        //此时要跳过中间这一个,因为i这个字符出现的次数小于k
        //但是这个字符出现了可能不止1次,用while来跳过它
        while(i<s.length() && hash[s[i]-'a'] < k) i++;
        int r = longestSubstring(s.substr(i),k);

        return max(l,r);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值