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

一、题目

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

二、思路

分治思路:

  1. 对于当前String s,历遍并将所有字符进行出现次数记录
  2. 重新历遍String,如果发现其出现次数少于k,以当前i前后分别再调用longestSubstring(s.substring(0,i),k)以及longestSubstring(s.substring(i+1,s.length()),k)并取二者较大值
  3. 如果没有小于k的字符,直接返回当前string长度
  4. 完成分治之后直接返回

三、代码

复制代码
class Solution {
    public int longestSubstring(String s, int k) {
        int n = s.length();
        return dfs(s, 0, n - 1, k);
    }

    public int dfs(String s, int l, int r, int k) {
        int[] cnt = new int[26];
        for (int i = l; i <= r; i++) {
            cnt[s.charAt(i) - 'a']++;
        }

        char split = 0;
        for (int i = 0; i < 26; i++) {
            if (cnt[i] > 0 && cnt[i] < k) {
                split = (char) (i + 'a');
                break;
            }
        }
        if (split == 0) {
            return r - l + 1;
        }

        int i = l;
        int ret = 0;
        while (i <= r) {
            while (i <= r && s.charAt(i) == split) {
                i++;
            }
            if (i > r) {
                break;
            }
            int start = i;
            while (i <= r && s.charAt(i) != split) {
                i++;
            }

            int length = dfs(s, start, i - 1, k);
            ret = Math.max(ret, length);
        }
        return ret;
    }
}
复制代码

四、分析

复杂度分析

  • 时间复杂度:O(N⋅∣Σ∣),其中 N为字符串的长度,Σ 为字符集,本题中字符串仅包含小写字母,因此 ∣Σ∣=26|。由于每次递归调用都会完全去除某个字符,因此递归深度最多为 ∣Σ∣

  • 空间复杂度:O(∣Σ∣2)。递归的深度为 O(∣Σ∣),每层递归需要开辟 O(∣Σ∣)的额外空间。

 

posted @   ImreW  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示