문자열이 주어질때, 최대 2개로만 구성된 가장 긴 substring 길이를 리턴하라.
Input: s = "eceba"
Output: 3
Explanation: The substring is "ece" which its length is 3.
two pointer 문제
는 어떤 조건에서 right를 증가 시킬지, 그리고 어떤 조건에서 left를 증가시킬지를 먼서 생각해보는 전략을 사용하기.O(n) 이지만 빈도수를 체크할때 매번 hashtable 전체를 순회해야해서 비효율적인 방법. (Runtime: 426 ms)
#define TABLE_SIZE 128
#define max(a,b) (((a) > (b)) ? (a) : (b))
int check_nr_char(int *table)
{
int cnt = 0;
for (int i = 0; i < TABLE_SIZE; i++) {
if (table[i] != 0)
cnt++;
}
return cnt;
}
int lengthOfLongestSubstringTwoDistinct(char * s){
int table[TABLE_SIZE] = {0,};
int maxlen = 0;
int ssize = strlen(s);
int left = 0, right = 0;
table[s[right]]++;
while (right < ssize) {
if (check_nr_char(table) <= 2) {
maxlen = max(maxlen, right - left + 1);
right++;
table[s[right]]++;
} else {
table[s[left++]]--;
}
}
return maxlen;
}
빈도수를 체크할때 hashtable 크기만큼 순회하지 않고, 문자종류 갯수 cur_freq
변수값 하나를 조정해서 수행. 훨씬 효율적이고 빠르다. (Runtime: 22 ms, faster than 80.95%)
hashtable빈도수를 저장할때 0이었다면 총 문자종류개수를 +1 하고, 빈도수를 감소시킬때 0이 된다면 총 문자종류수를 -1 한다.
#define TABLE_SIZE 128
#define max(a,b) (((a) > (b)) ? (a) : (b))
int lengthOfLongestSubstringTwoDistinct(char * s){
int table[TABLE_SIZE] = {0,};
int maxlen = 0;
int ssize = strlen(s);
int left = 0, right = 0;
int cur_freq = 1;
table[s[right]]++;
while (right < ssize) {
if (cur_freq <= 2) {
maxlen = max(maxlen, right - left + 1);
right++;
if (table[s[right]] == 0)
cur_freq++;
table[s[right]]++;
} else {
if (table[s[left]] == 1)
cur_freq--;
table[s[left++]]--;
}
}
return maxlen;
}
위와 동일한 로직인데 아래 코드가 더 논리적으로 이해하기 쉽고 간결. 속도도 더 빠르게 나왔음.
(Runtime: 12 ms, faster than 100.00%)
#define TABLE_SIZE 128
#define max(a,b) (((a) > (b)) ? (a) : (b))
int lengthOfLongestSubstringTwoDistinct(char * s){
int table[TABLE_SIZE] = {0,};
int maxlen = 0;
int ssize = strlen(s);
int left = 0, right = 0;
int cur_freq = 0;
while (right < ssize) {
table[s[right]]++;
if (table[s[right]] == 1)
cur_freq++;
if (cur_freq <= 2) {
maxlen = max(maxlen, right - left + 1);
} else {
table[s[left]]--;
if (table[s[left]] == 0)
cur_freq--;
left++;
}
right++;
}
return maxlen;
}