動機
搞懂調整sliding window的條件
Problem
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 greater than or equal to k
.
Example 1:
Input: s = aaabb, k = 3Output: 3Explanation: The longest substring is aaa, as 'a' is repeated 3 times.
Example 2:
Input: s = ababbc, k = 2Output: 5Explanation: 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
Sol: divide-and-conquer
無腦一直分割,一邊統計,一邊看有沒有不合的,就繼續分割
class Solution:
def f(self,i,j):
if j-i <= 1:
return j-i if j-i >= self.k else 0
else:
tbl = Counter(self.s[i:j])
for k in range(i,j):
if tbl[self.s[k]] < self.k:
return max(self.f(i,k), self.f(k+1,j))
return j-i if j-i >= self.k else 0
def longestSubstring(self, s: str, k: int) -> int:
self.s = list(s)
self.k = k
return self.f(0,len(s))
Sol2: sliding window
當初第一眼看到就想用,但是沒有用成,因為無法判斷,要怎麼往上漲,往右縮
根本原因是同時牽扯到
- 長度
- 字母數
長度當然是越長越好,但要怎麼判斷要讓windows停止生長與縮小,如果不限制字母數會無法判斷該漲還是該縮
所以要把其中一個固定下來,因為要找的是長度,所以變成固定字母數,以此為條件讓windows變化
class Solution:
def longestSubstring(self, s: str, k: int) -> int:
s = list(s)
ret = 0
for maxDiffAlpha in range(1,len(set(s))+1):
i = 0
j = 0
cnt = {}
cntAlpha = 0
howManyK = 0
while j < len(s):
if cntAlpha <= maxDiffAlpha:
if cnt.get(s[j],0) == 0:
cnt[s[j]] = 0
cntAlpha += 1
cnt[s[j]] += 1
if cnt[s[j]] == k:
howManyK += 1
j += 1
else:
if cnt[s[i]] == k:
howManyK -= 1
cnt[s[i]] -= 1
if cnt[s[i]] == 0:
cntAlpha -= 1
i += 1
if cntAlpha == maxDiffAlpha and cntAlpha == howManyK:
ret = max(ret, j-i)
return ret