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

这篇博客探讨了一种算法问题,即如何找到一个字符串中最长的子串,其所有字符出现的频率都大于等于给定的阈值k。通过递归实现,首先计算每个字符的出现次数,然后分割字符串,对每个小于k计数的子串进行处理。如果无需分割,直接返回原字符串;否则,递归查找最大长度的子串。最后,处理最后一段,确保满足条件。这种方法涉及到字符串处理、递归和动态规划等概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目——对所有字符出现频率进行大于等于k的限制

思路

  1. 递归实现分割
  2. 利用计数小于k的字母进行分割
  3. 利用段需要大于k且大于当前res 来过滤小段

代码

步骤:
1. 全体计数
2. 根据计数与k的关系进行小于k的统计
3. 判断是否需要分割——无需分割返回整个字符串
4. 需要分割——循环、递归查找最大值
5. 对于最后一段进行考虑——当最后一个元素计数大于k时 该段会被遗弃

class Solution {
public:
    int longestSubstring(string s, int k) {
        // 遍历获取每个字符的个数,用于判断是否小于k
        unordered_map<char, int> m;
        for (auto& c : s)
            ++m[c];

        // 遍历把字符串按照小于k的数量拆分成多段,分开来解决
        vector<int> splits;
        int n = s.size();
        for (int i = 0; i < n; ++i)
            if (m[s[i]] < k)
                splits.push_back(i);

        // 无需拆分,则返回整段字符串
        if (splits.size() <= 0)
            return s.size();


        // 递归返回最大长度
        int res = 0;
        int left = 0;
        for (int i = 0; i < splits.size(); ++i){
            int len = splits[i] - left;
            if (len >= k && len > res)// 至少要大于k,否则肯定是不满足的
                res = max(res, longestSubstring(s.substr(left, len), k));
            left = splits[i] + 1;
        }

        // 考虑最后一段
        if (left < n-1)
            res = max(res, longestSubstring(s.substr(left, n-1-left+1), k));
        
        return res;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值