Recursion
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
| class Solution { public int longestSubstring(String s, int k) { if (s.length() < k) { return 0; }
int[] countMap = new int[26]; for (int i = 0; i < s.length(); i++) { countMap[s.charAt(i) - 'a']++; }
for (int i = 0; i < countMap.length; i++) { if (countMap[i] > 0 && countMap[i] < k) { int maxLength = 0; for (String subStr : s.split(String.valueOf((char) (i + 'a')))) { maxLength = Math.max(maxLength, longestSubstring(subStr, k)); } return maxLength; } }
return s.length(); } }
|
Sliding Window
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
| class Solution { public int longestSubstring(String s, int k) { if (s.length() < k) { return 0; }
int maxLength = 0; for (int targetDistinctCharCount = 1; targetDistinctCharCount <= 26; targetDistinctCharCount++) { int[] windowMap = new int[26]; int distinctCharCount = 0; int kCharCount = 0; int i = 0; for (int j = 0; j < s.length(); j++) { char rightmost = s.charAt(j); if (windowMap[rightmost - 'a'] == 0) { distinctCharCount++; } if (++windowMap[rightmost - 'a'] == k) { kCharCount++; }
while (distinctCharCount > targetDistinctCharCount) { char leftmost = s.charAt(i++); if (windowMap[leftmost - 'a']-- == k) { kCharCount--; } if (windowMap[leftmost - 'a'] == 0) { distinctCharCount--; } }
if (kCharCount == targetDistinctCharCount) { maxLength = Math.max(maxLength, j - i + 1); } } }
return maxLength; } }
|
此题与常规滑动窗口思路不同的点在于若不固定用到的不同字符的个数,则无法判断何时收缩窗口,因为收缩窗口与求最长的长度是相悖的。当固定了用到的不同字符的个数时,就能明确收缩窗口的目标。
References
395. Longest Substring with At Least K Repeating Characters