leetcode.com/problems/longest-palindromic-substring/
핵심 아이디어
팰린드롬 문자열이란 문자를 거꾸로 했을때 기존의 문자열과 같은 문자열을 뜻한다.
이 문제를 해결하는 방법은 많으나 여기서 소개하는 방법은 DP를 이용한 방법이다.
여기서 가장 중요한 핵심은 "현재 문자열의 양끝 문자가 같고 내부의 문자열이 펠린드롬이면 그 문자열은 펠린드롬이다."이다.
즉, ababa은 ababa 으로 양끝이 같은데, 내부 문자열인 ababa 가 펠린드롬이기 때문에, 펠린드롬 문자열이라고 판단할 수 있다.
이 점을 이용하여 dp[i][j] 를 문자열 i~j까지 펠린드롬 여부로 정의하여 문자열의 길이가 1,2 인 경우를 전처리해주고,
그 이상 문자열은 현재 문자열의 양끌을 체크하고 해당 문자열의 i+1~j-1까지의 범위가 펠린드롬인지를 판단하고
만약 펠린드롬이면 가장 긴 펠린드롬 문자열을 업데이트하는 방식으로 문제를 해결할 수 있다.
/**
* @param {string} s
* @return {string}
*/
var longestPalindrome = function (s) {
let ans = '';
// dp[a][b] : s의 a~b까지는 펠린드롬인가?
const dp = Array.from({ length: s.length+1 }, () =>
Array.from({ length: s.length+1 }, () => false)
);
// i부터 i까지는 1자리 아므로 항상 펠린드롬이다.
for (let i = 0; i < s.length; i++) {
dp[i][i] = true;
ans = s[i];
}
// i부터 i+1까지는 2자리이므로 2자리가 같은경우 팰린드롬이다.
for (let i = 0; i < s.length; i++) {
if (s[i] === s[i + 1]) dp[i][i + 1] = true;
if (dp[i][i + 1]) ans = s.slice(i, i + 2);
}
for (let i = s.length - 1; i >= 0; i--) {
for (let j = i + 2; j < s.length; j++) {
// 양끝이 같고, 안쪽의 문자열이 펠린드롬이면 지금 문자열도 펠린드롬!
dp[i][j] = dp[i + 1][j - 1] && s[i] === s[j];
if (dp[i][j]) {
ans = ans.length < (j - i + 1) ? s.slice(i, j + 1) : ans;
}
}
}
return ans;
};
'개발 > 알고리즘' 카테고리의 다른 글
[LeetCode] 101. Symmetric Tree (0) | 2021.01.27 |
---|---|
[LeetCode] 122. Best Time to Buy and Sell Stock II (0) | 2021.01.26 |
[LeetCode] 8. String to Integer (atoi) (0) | 2021.01.22 |
[Javascript][LeetCode] Reverse Integer (0) | 2021.01.17 |
[Javascript][BOJ] 1302 베스트 셀러 (0) | 2021.01.14 |