• LeetCode 395. 至少有K个重复的最长子串


    题目描述

    给你一个字符串 s 和一个整数 k ,请你找出 s 中的最长子串, 要求该子串中的每一字符出现次数都不少于 k 。返回这一子串的长度。

    示例1:

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

    示例2:

    输入:s = "ababbc", k = 2
    输出:5
    解释:最长子串为 "ababb" ,其中 'a' 重复了 2 次, 'b' 重复了 3 次。
    

    提示:

    • 1 <= s.length <= 104
    • s 仅由小写英文字母组成
    • 1 <= k <= 105

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/longest-substring-with-at-least-k-repeating-characters

    思路解析

    直接采用暴力枚举的方法不可取,时间复杂度为 (O(n^3)),想办法降低时间复杂度。这里采用分治的方法来加速。

    1. 若某一字符 cs 中出现的次数小于 k 次,那么可以确定最长的子串一定不包含 c,可以将 s 在所有 c 出现的地方进行分割,然后计算各个分割得到的子串中符合要求的最大子串。
    2. 若不存在这样的字符 c,那么直接返回 s 的长度即可。

    代码实现

    class Solution {
    public:
        int longestSubstring(string s, int k) {
            if(s.empty()) return 0;
            unordered_map<char, vector<int>> smap;
            for(int i = 0; i < s.length(); i++) {
                smap[s[i]].push_back(i);
            }
            for(auto p : smap) {
                if(p.second.size() < k) {
                    int maxLen = longestSubstring(s.substr(0, p.second[0]), k);
                    for(int i = 0; i < p.second.size(); i++) {
                        int nextPos = (i == p.second.size() - 1) ? s.length() : p.second[i + 1];
                        string tmpStr = s.substr(p.second[i] + 1, nextPos - p.second[i] - 1);
                        int tmpLen = longestSubstring(tmpStr, k);
                        maxLen = max(maxLen, tmpLen);
                    }
                    return maxLen;
                }
            }
            return s.length();
        }
    }; 
    
  • 相关阅读:
    jdk动态代理
    mysql-索引方案
    闭包的有点以及出现的内存泄露2016/4/12
    表单2016/4/8
    cursor
    同一个事件绑定不同的函数
    a:link visited hover active
    对于属性操作,加入属性,移除属性
    offset获取位置
    清除浮动6中方法
  • 原文地址:https://www.cnblogs.com/xqmeng/p/14455479.html
Copyright © 2020-2023  润新知