395. 至少有 K 个重复字符的最长子串
一、题目
给你一个字符串 s
和一个整数 k
,请你找出 s
中的最长子串, 要求该子串中的每一字符出现次数都不少于 k
。返回这一子串的长度。
二、思路
分治思路:
- 对于当前String s,历遍并将所有字符进行出现次数记录
- 重新历遍String,如果发现其出现次数少于k,以当前i前后分别再调用longestSubstring(s.substring(0,i),k)以及longestSubstring(s.substring(i+1,s.length()),k)并取二者较大值
- 如果没有小于k的字符,直接返回当前string长度
- 完成分治之后直接返回
三、代码
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(∣Σ∣)的额外空间。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了