Problem: 395. 至少有 K 个重复字符的最长子串
文章目录
- 思路
- 解题方法
- 复杂度
- Code
思路
这是一道关于字符串处理的问题,我们需要找到至少有 K 个重复字符的最长子串。我们可以使用滑动窗口的方法来解决这个问题。我们可以设置一个窗口,然后不断地移动这个窗口,同时统计窗口内的字符数量,当窗口内的某个字符数量达到 K 时,我们就尝试更新最长子串的长度。
解题方法
我们使用一个数组 cnts 来统计窗口内的字符数量,然后使用两个指针 l 和 r 来表示窗口的左右边界。我们不断地移动右边界 r,每移动一次,我们就更新 cnts 数组,同时检查窗口内的字符数量是否满足条件。如果满足条件,我们就尝试更新最长子串的长度。当窗口内的字符种类超过我们设定的种类数 require 时,我们就移动左边界 l,直到窗口内的字符种类数不超过 require。
复杂度
时间复杂度:
O ( n ) O(n) O(n),其中 n 是字符串的长度。我们需要遍历整个字符串。
空间复杂度:
O ( 1 ) O(1) O(1),我们只需要常数级别的空间来存储 cnts 数组和几个变量。
Code
class Solution {public int longestSubstring(String str, int k) {char[] s = str.toCharArray();int[] cnts = new int[256];int n = s.length;int ans = 0;// collect 窗口中字符串的种类// satisfy 窗口中大于等于k个数的字符串个数for (int require = 1; require <= 26; require++) {Arrays.fill(cnts, 0);for (int l = 0, r = 0, collect = 0, satisfy = 0; r < n; r++) {cnts[s[r]]++;if (cnts[s[r]] == 1) {collect++;}if (cnts[s[r]] == k) {satisfy++;}// 种类超了// 吐出相应的字符串while (collect > require) {if (cnts[s[l]] == 1) {collect--;}if (cnts[s[l]] == k) {satisfy--;}cnts[s[l++]]--;}if (satisfy == require) {ans = Math.max(ans, r - l + 1);}}}return ans;}
}