문제 링크
요약
- 1차원 DP
최종
결과
- 우선, character 가 마지막으로 등장한 index 들을 담고 있는 array
idxs가 있다고 해보자.- 예를 들어
s[i] == 'a'라면idxs['a'] == i이다. - 아직 등장하지 않은 character 에 대해서는
-1의 값을 가진다. 따라서 처음에는 전부-1로 초기화된다.
- 예를 들어
- 그리고
dp[i]를 생각해 보자.dp[i]는s[i]로 끝나는 substring 중에, 조건을 만족하는 가장 긴 놈의 길이이다.- 그럼 이놈을 계산해나가는 방법을 알아보자.
- 우선
idx[s[i]] == -1라면 아직 이 character 가 등장하지 않은것이기 때문에, 이전의 길이 +1 을 해주면 된다. 즉,dp[i] = dp[i - 1] + 1이다. - 그렇지 않다면 이 character 가 어디서 등장했는지를 봐야 한다.
- Index
i - 1로 끝나고 조건을 만족하는 substring 의 최대 길이가dp[i - 1]이므로, 이 substring 은 indexi - dp[i - 1]부터i - 1까지다. - 만약
i - dp[i - 1] <= idx[s[i]]라면dp[i - 1]이 나타내는 substring 안에s[i]가 등장한다는 뜻이므로idxs[s[i]] + 1부터i까지가 최대 길이다. 그래서dp[i] = i - idxs[s[i]]가 된다. - 그렇지 않다면,
dp[i - 1]이 나타내는 substring 안에s[i]가 등장하지 않는다는 뜻이다. 그럼dp[i] = dp[i - 1] + 1이다.
- Index
- 우선
- 이걸 코드로 구현하면 다음과 같다.
idxs는map사용하니까 너무 느려서array사용했다.- 위에서 보면 항상
dp[i - 1]만 사용된다. 그래서 vector 사용하지 말고prev_len로 바꿨다.
class Solution {
array<int, 128> idxs;
public:
int lengthOfLongestSubstring(string s) {
int n = s.size();
if (n < 2) {
return n;
}
int prev_len = 1;
int max_len = 1;
for (int i = 0; i < 128; i++) {
idxs[i] = -1;
}
idxs[s[0]] = 0;
for (int i = 1; i < n; i++) {
if (i - prev_len <= idxs[s[i]]) {
prev_len = i - idxs[s[i]];
} else {
prev_len = prev_len + 1;
max_len = max(max_len, prev_len);
}
idxs[s[i]] = i;
}
return max_len;
}
};