프로그래머스 - 가장 긴 팰린드롬 (Lv.3)

1 minute read

문제 설명

  • 길이가 n(2500이하)인 문자열이 주어질 때, 부분문자열 중에서 가장 긴 팰린드롬의 길이를 구하라

구현 (TC 2개 Fails, 효율성 테스트 시간초과)

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

// 부분문자열이 펠린드롬인지 확인한다.
bool check_palindrome(string& org_str, int n, int front, int back){
    for(int i=0; i<n/2; i++){
        if(org_str[front+i] != org_str[back-i])
            return false;
    }
    return true;
}

// 문자열 파싱의 시작점, 끝점을 인자로 받아서 부분문자열을 만든다.
int get_len_substr_palindrome(string& org_str, int start, int end){
    int n = end - start + 1;

    if(check_palindrome(org_str, n, start, end))
        return n;
    else
        return 0;
}

int solution(string s)
{
    int answer=0;
    int n = s.length();
    
    for(int i=0; i<n-1; i++){
        for(int j=n-1; j>=i+1; j--){
            answer = max(answer, get_len_substr_palindrome(s, i, j));
        }
    }
    
    return answer;
}

개선한 점

  • 모든 경우의 수에 대해서 탐색할 필요가 없다. 길이가 n인 부분문자열 중에서 펠린드롬을 찾아가고, 펠린드롬을 찾을 수 없는 경우 길이를 줄여간다.
  • 투포인터를 통해 시간복잡도를 최대한 줄였다. 부분문자열의 맨 앞과 맨 뒤를 가리키는 front, back 변수를 두어 palindrome을 확인하였다.
  • 부분문자열의 길이가 줄어들수록 front, back을 결정할 수 있는 경우의 수는 늘어나는데, 이에 대한 주의가 필요하다.

구현 (All pass)

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

bool check_palindrome(string& str, int len, int start, int end){
    for(int i=0; i<len/2; i++){
        if(str[start+i] != str[end-i])
            return false;
    }
    return true;
}

bool get_longest_palindrome(string& str, int substr_len){
    int orgstr_len = str.length();
    int diff = orgstr_len - substr_len;
    
    int start = 0, end = orgstr_len-1;
    int front, back;
    for(int i=0; i<=diff; i++){
        front = start + i;
        back = end - (diff-i);
        if(check_palindrome(str, substr_len, front, back))
            return true;
    }
    return false;
}

// 모든 경우의 수를 탐색하는 것이 아니라 길이가 최대인 팰린드롬부터 찾는다.
int solution(string s)
{
    int answer=0;
    int n = s.length();
    
    for(int substr_len=n; substr_len>0; substr_len--){
        if(get_longest_palindrome(s, substr_len)) {
            answer = substr_len;
            return answer;
        }
    }
    
    answer=1;
    return answer;
}

Leave a comment