[LeetCode] 395. Longest Substring with At Least K Repeating Characters
阿新 • • 發佈:2020-11-27
Given a strings
and an integerk
, returnthe length of the longest substring ofs
such that the frequency of each character in this substring is greater than or equal tok
.
Example 1:
Input: s = "aaabb", k = 3 Output: 3 Explanation: The longest substring is "aaa", as 'a' is repeated 3 times.
Example 2:
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:
1 <= s.length <= 104
s
consists of only lowercase English letters.1 <= k <= 105
至少有K個重複字元的最長子串。
找到給定字串(由小寫字元組成)中的最長子串T,要求T中的每一字元出現次數都不少於k。輸出T的長度。
這道題我提供一個滑動視窗的思路。首先暴力解就是以一個 O(n^2) 的複雜度去遍歷input字串,看看字串中是否存在一個 [s.charAt(j), s.charAt(i)] 的子串滿足題意。這個做法會超時。這道題還有分治的思路,但是我個人覺得不是很好想所以這裡不列出了。
這裡我們把題目要求拆分一下。既然題目說了只有小寫字母(這裡我非常懷疑,因為用陣列統計的時候如果陣列長度只建立成26是會越界的),那麼我們可以從1到26去試探。這裡我們試探的是找一個子串,其中包含了一個,兩個,三個或者。。26個不同字元,每個字元出現次數不少於K。這樣一來我們就可以把題目轉化成類似159和340那樣的做法了。
時間O(n)
空間O(n)
Java實現
1 class Solution { 2 public int longestSubstring(String s, int k) { 3 int res = 0; 4 // 試探input字串中是否能找到一個最長的字串,存在有numUniqueTarget個不同字元5 // 我們這裡是從1 - 26一個個去試探 6 for (int numUniqueTarget = 1; numUniqueTarget <= 26; numUniqueTarget++) { 7 res = Math.max(res, helper(s, k, numUniqueTarget)); 8 } 9 return res; 10 } 11 12 // sliding window模板 13 private int helper(String s, int k, int i) { 14 int[] map = new int[256]; 15 int start = 0; 16 int end = 0; 17 int res = Integer.MIN_VALUE; 18 // 子串內unique的字母個數 19 int counter = 0; 20 // 出現次數不少於K的字母個數 21 int numNoLessThanK = 0; 22 while (end < s.length()) { 23 char c1 = s.charAt(end); 24 if (map[c1]++ == 0) { 25 counter++; 26 } 27 if (map[c1] == k) { 28 numNoLessThanK++; 29 } 30 end++; 31 32 while (counter > i) { 33 char c2 = s.charAt(start); 34 if (map[c2]-- == k) { 35 numNoLessThanK--; 36 } 37 if (map[c2] == 0) { 38 counter--; 39 } 40 start++; 41 } 42 43 if (counter == numNoLessThanK) { 44 res = Math.max(res, end - start); 45 } 46 } 47 return res; 48 } 49 }