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

题意简述

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

算法分析

法一 分治

如果某个字符在整个字符串中的出现次数不足 kk ,那么任意一个包含这个字符的子串都不可能满足条件。这就好像整个字符串被这个字符分割成了几个子段,满足条件的子串只可能在子段中取。反之,如果该字符串中所有字符出现次数都不少于 kk ,那么该串即符合条件,可以去更新最值。考虑使用分支递归。

法二 滑动窗口

挖坑

代码实现

法一 分治

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class Solution {
public:
int dfs(const string& s, int l, int r, int k) {
vector<int> cnt(26, 0);
for (int i = l; i <= r; i++) {
cnt[s[i] - 'a']++;
}

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

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

int length = dfs(s, start, i - 1, k);
ret = max(ret, length);
}
return ret;
}

int longestSubstring(string s, int k) {
int n = s.length();
return dfs(s, 0, n - 1, k);
}
};

法二 滑动窗口

挖坑