1. 程式人生 > 實用技巧 >[LeetCode] 395. Longest Substring with At Least K Repeating Characters

[LeetCode] 395. Longest Substring with At Least K Repeating Characters

Given a stringsand an integerk, returnthe length of the longest substring ofssuch 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
  • sconsists 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 }

sliding window相關題目

LeetCode 題目總結