zoukankan      html  css  js  c++  java
  • 【LeetCode-递归】至少有K个重复字符的最长子串

    题目描述

    找到给定字符串(由小写字符组成)中的最长子串 T , 要求 T 中的每一字符出现次数都不少于 k 。输出 T 的长度。
    示例:

    输入:
    s = "aaabb", k = 3
    输出:
    3
    最长子串为 "aaa" ,其中 'a' 重复了 3 次。
    

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

    思路

    使用两个指针 left, right 表示在 [left, right] 范围内进行判断。首先统计 [left, right] 范围内字母的出现次数存入数组 cnt 中,然后根据字母出现的次数是否大于等于 k,从两边缩小范围。缩小范围后,判断新范围内是否有字符出现的次数小于 k,如果有,说明该字符不可能出现在结果当中,假设该字符的下标为 mid,则递归统计 [left, mid-1] 和 [mid+1, right] 范围内符合条件的长度,取较大者;否则,说明 [left, right] 范围内的字符出现次数均大于等于 k,返回范围的长度 right-left+1.

    代码如下:

    class Solution {
    public:
        int longestSubstring(string s, int k) {
            if(s.empty() || s.size()<k) return 0;
            
            return count(s, k, 0, s.size()-1);
        }
    
        int count(string s, int k, int left, int right){
            if(right-left+1<k) return 0;
    
            vector<int> cnt(26, 0);
            for(int i=left; i<=right; i++) cnt[s[i]-'a']++;
    
            while(right-left+1>=k && cnt[s[left]-'a']<k) left++;
            while(right-left+1>=k && cnt[s[right]-'a']<k) right--;
            if(right-left+1<k) return 0;
    
            for(int mid = left; mid<=right; mid++){
                if(cnt[s[mid]-'a']<k){
                    return max(count(s, k, left, mid-1), count(s, k, mid+1, right));
                }
            }
            return right-left+1;
        }
    };
    

    参考

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

  • 相关阅读:
    Senventh Week(补充完整)
    Sixth Week(补充完整)
    Fifth Week(补充完整)
    Fourth Week (补充完整)
    九大内置对象
    matlab 简单绘图
    matlab ./
    困惑
    【转】matlab中inf
    matlab x~=0
  • 原文地址:https://www.cnblogs.com/flix/p/13332635.html
Copyright © 2011-2022 走看看