문제설명:
문자열을 입력받아 부분 문자열 중 가장 긴 (palindrome)*의 길이를 리턴해야 합니다.
입력
인자 1 : str
출력
주의사항
입출력 예시
let str = 'My dad is a racecar athlete';
let result = longestPalindrome(str);
console.log(result); // --> 11 ('a racecar a')
str = ' dad ';
result = longestPalindrome(str);
console.log(result); // --> 5 (' dad ')
풀이코드 1 :
// naive solution: O(N^3)
// function longestPalindrome(str) {
// if (str.length <= 1) return str.length;
// const checkPalindrome = function (str) {
// const half = parseInt(str.length / 2);
// for (let i = 0; i < half; i++) {
// if (str[i] !== str[str.length - 1 - i]) return false;
// }
// return true;
// };
// // 길이가 긴 순서대로 부분 문자열을 만들어 검사한다.
// for (let len = str.length; len >= 1; len--) {
// // 길이 len인 부분 문자열들의 시작 인덱스를 구한다.
// // 예. 전체 길이가 100이고, 부분 문자열의 길이가 10인 경우,
// // 부분 문자열 (시작인덱스 ~ 마지막 인덱스)
// // 90 ~ 99, 89 ~ 98, 88 ~ 97, ..., 1 ~ 10, 0 ~ 9
// for (let startIdx = str.length - len; startIdx >= 0; startIdx--) {
// // slice의 특성을 고려한 마지막 인덱스 + 1 을 저장
// const endIdx = startIdx + len;
// const subStr = str.substring(startIdx, endIdx);
// const result = checkPalindrome(subStr);
// if (result === true) return len;
// }
// }
// }
function longestPalindrome(str) {
if (str.length < 2) return str.length;
const LENGTH = str.length;
const isPalindrome = Array(LENGTH)
.fill(false)
.map((_) => Array(LENGTH).fill(false));
// 언더바는 잘못된 코드가 아닙니다.
// 언더바는 어떤 매개변수는 전달되어도 무시하겠다는 의미로 사용됩니다.
let maxLen = 1;
// 길이가 1인 회문
for (let i = 0; i < LENGTH; i++) isPalindrome[i][i] = true;
// 길이가 2인 회문
for (let i = 0; i < LENGTH - 1; i++) {
if (str[i] === str[i + 1]) {
isPalindrome[i][i + 1] = true;
maxLen = 2;
}
}
// 길이가 3 이상인 회문
for (let len = 3; len <= LENGTH; len++) {
for (let startIdx = 0; startIdx <= LENGTH - len; startIdx++) {
const endIdx = startIdx + len - 1;
if (
isPalindrome[startIdx + 1][endIdx - 1] === true &&
str[startIdx] === str[endIdx]
) {
isPalindrome[startIdx][endIdx] = true;
maxLen = len;
}
}
}
return maxLen;
}
풀이 코드 2:
위 풀이 코드1의 시간 복잡도는 O(n^3)입니다. 다음과 같이 알고리즘을 개선하여 시간 복잡도를 O(n^2)으로 줄일 수 있습니다.
위 알고리즘에서 팰린드롬의 중심은 문자열의 길이가 홀수인 경우 문자열의 중앙 글자, 짝수인 경우 중앙 두 글자입니다. 중심을 기준으로 문자열을 확장해 나가면서 팰린드롬을 찾습니다. 이 때, 확장하는 도중 팰린드롬이 아닌 경우에는 더 이상 확장하지 않고 다음 중심으로 넘어간다.
function longestPalindrome(str) {
if (str.length < 2) return str.length;
let maxLength = 1;
let start = 0;
for (let i = 1; i < str.length; i++) {
// 팰린드롬 중심이 한 글자일 때
let left = i - 1;
let right = i + 1;
while (left >= 0 && right < str.length && str[left] === str[right]) {
const length = right - left + 1;
if (length > maxLength) {
maxLength = length;
start = left;
}
left--;
right++;
}
// 팰린드롬 중심이 두 글자일 때
left = i - 1;
right = i;
while (left >= 0 && right < str.length && str[left] === str[right]) {
const length = right - left + 1;
if (length > maxLength) {
maxLength = length;
start = left;
}
left--;
right++;
}
}
return maxLength;
}
let str = 'My dad is a racecar athlete';
let result = longestPalindrome(str);
console.log(result); // --> 11 ('a racecar a')
str = ' dad ';
result = longestPalindrome(str);
console.log(result); // --> 5 (' dad ')
JavaScript Algorithm - gossipProtocol2 (0) | 2023.03.02 |
---|---|
JavaScript Algorithm - countIslands (0) | 2023.03.01 |
JavaScript Algorithm - jobAllocation (0) | 2023.02.27 |
JavaScript Algorithm - decompression (0) | 2023.02.24 |
JavaScript Algorithm - coinChange (0) | 2023.02.23 |