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; } }