Find the length of the longest substring T of a given string (consists of lowercase letters only) such that every character in T appears no less than k times.
문자열이 최소 k번 등장하는 가장 긴 부분 문자열 찾기
Example 1:
Input: s = "aaabb", k = 3 Output: 3 The longest substring is "aaa", as 'a' is repeated 3 times.
Example 2:
Input: s = "ababbc", k = 2 Output: 5 The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is repeated 3 times.
접근 방법:
브루트포스는 tle
1. 재귀사용
문자열 ababcabaadc를 보자. k=2이다.
가장 긴 문자열을 파괴하는 알파벳은 한 개밖에 없는 d이다. 이제 d를 기준으로 문자 앞뒤를 잘라서 다시 긴 문자열을 따진다.
일반화하자면,
문자열을 구간별로 돌면서 조건을 파괴하는 문자를 기준으로 앞뒤를 자른다. (next = mid+1)
앞뒤를 기준으로 다시 가장 긴 문자열을 리턴한다. (return max(recur(start, mid), recur(next, end))
문자열 구간이 모두 조건을 만족한다면 return end-start를 할것이고 그게 아니라면 계속 문자가 앞뒤로 divide 될 것이다.
class Solution {
public int recursive(String s, int start, int end, int k){
if(end < k) return 0;
int[] count = new int[26];
for(int i=start; i<end; i++){
count[s.charAt(i)- 'a']++;
}
for(int mid = start; mid<end; mid++){
if(count[s.charAt(mid) - 'a'] >= k) continue;
int next = mid + 1;
while(next < end && count[s.charAt(next) - 'a'] < k) next++;
return Math.max(recursive(s, start, mid, k), recursive(s, next, end, k));
}
return end - start;
}
public int longestSubstring(String s, int k) {
int n = s.length();
return recursive(s, 0, n, k);
}
}
2. 투포인터(슬라이딩 윈도우) 사용
문자열 전체에서 unique 알파벳수를 센다.
start, end사이에서 문자열을 구성하고 있는 알파벳수를 기준으로 가장 긴 문자열 구간을 체크한다.
class Solution {
public:
int longestSubstring(string s, int k) {
int count[26]={0,};
int maxUnique = 0;
int len = s.length();
for(int i=0; i<len; i++){
count[s[i]-'a']++;
if(count[s[i] - 'a'] == 1){
maxUnique++;
}
}
int result = 0;
for(int cur=1; cur<=maxUnique; cur++){
fill(count, count+26, 0);
int start=0, end=0, unique=0,countK=0;
while(end < len){
if(unique <= cur){
if(count[s[end] - 'a'] == 0) unique++;
count[s[end] - 'a']++;
if(count[s[end] - 'a'] == k) countK++;
end++;
}else {
if(count[s[start]-'a'] == k) countK--;
count[s[start]-'a']--;
if(count[s[start]-'a'] == 0) unique--;
start++;
}
if(unique == countK && unique == cur){
result = max(result, end-start);
}
}
}
return result;
}
};
'알고리즘 문제풀이 > leetcode' 카테고리의 다른 글
[leetcode 7] Reverse Integer (0) | 2020.11.15 |
---|---|
[leetcode 387] First Unique Character in a String (0) | 2020.11.14 |
[leetcode 454] 4Sum II (0) | 2020.11.14 |
[leetcode 36] Valid Sudoku (0) | 2020.11.13 |
[leetcode 29] Divide Two Integers (0) | 2020.11.13 |
댓글