Given a string s
and an integer k
, return the length of the longest substring of s
such that the frequency of each character in this substring is less than or equal to k
.java
Example 1:less
Input: s = "aaabb", k = 3 Output: 3 Explanation: The longest substring is "aaa", as 'a' is repeated 3 times.
Example 2:this
Input: s = "ababbc", k = 2 Output: 5 Explanation: The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is repeated 3 times.
Constraints:code
1 <= s.length <= 10^4
s
consists of only lowercase English letters.1 <= k <= 10^5
在指定字符串中找到一个最长的子串,使其包含的每一个字母出现的次数都大于等于一个阈值。leetcode
求子串问题通常都会想到滑动窗口,但由于本题是要求超过阈值,直接用滑动窗口很难想出一个用来判断该缩短仍是伸长窗口的标准。官方解答提供了一个很巧妙的思路:一个子串能拥有的不一样字符的种类是受原字符串限制的,因此能够将窗口变更的依据定为“当前子串拥有的不一样字符的个数”,这样最多进行26次遍历便可获得答案。字符串
class Solution { public int longestSubstring(String s, int k) { int ans = 0; int uniqueCount = 0; boolean[] exist = new boolean[26]; for (char c : s.toCharArray()) { if (!exist[c - 'a']) { exist[c - 'a'] = true; uniqueCount++; } } for (int ceil = 1; ceil <= uniqueCount; ceil++) { int unique = 0, satisfied = 0, start = 0, end = 0; int[] count = new int[26]; while (end < s.length()) { if (unique <= ceil) { int index = s.charAt(end) - 'a'; if (count[index] == 0) unique++; count[index]++; if (count[index] == k) satisfied++; end++; } else { int index = s.charAt(start) - 'a'; if (count[index] == k) satisfied--; count[index]--; if (count[index] == 0) unique--; start++; } if (unique == ceil && unique == satisfied) { ans = Math.max(ans, end - start); } } } return ans; } }