반응형
Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

코딩하기 좋은날

백준 14444 가장 긴 팰린드롬 부분 문자열 본문

백준(Baekjoon) 문제

백준 14444 가장 긴 팰린드롬 부분 문자열

huiung 2020. 3. 22. 15:18
반응형

 

 

주어진 문자열에서 가장 긴 팰린드롬 부분 문자열을 찾는 문제입니다.

문자열의 길이가 10만이므로 단순히 찾아보는 방법으론 해결을 할 수 없고 Manacher의 알고리즘을 이용하여야 합니다.

이 알고리즘은 배열에 현재 위치에서 가장 긴 팰린드롬의 길이를 저장함으로써 O(N) 만에 가장 긴 팰린드롬을 찾을 수 있는데 palin[i] -> i를 중심으로 길이가 가장긴 팰린드롬 길이의 절반값을 의미합니다.

 

이 과정을 거치기전에 짝수 길이 팰린드롬도 찾기 위하여 입력받는 문자열 양단에 #을 모두추가해주고 시작합니다.

 

maxlen이라는 변수에 i+palin[i] 값이 가장 큰 값을 유지시켜 주는데 즉 팰린드롬중 현재 가장 오른쪽 끝에 위치한 부분을 저장 하겠다는 의미입니다. 이 값을 저장 함으로써 다음 인덱스를 진행할때 그 인덱스가 이안에 포함 되있는지 안되있는지 여부에 따라 palin 값을 결정 할 수 있게 됩니다.

 

현재 maxlen에 들어있는 펠린드롬 내부에 지금 진행하는 인덱스가 포함 되어있다면 이때의 palin[i] 의 초기값은

min(palin[2*cur-i], maxlen-i) 이 값이 됩니다. 첫번째에 있는 값인 경우는 i와 대칭적 위치에 있는 palin의 값이 현재 maxlen의 펠린드롬을 초과하지 않는 경우 입니다. 초과하지 않는다면 이 값을 취하고 초과하게 된다면 maxlen-i 값( 이 값은 maxlen이 포함된 펠린드롬의 2*cur-i ~ i 까지의 펠린드롬 길이)을 취해주면 됩니다. 이후 그 이상의 문자들을 비교하여 palin 값을 정해주면 됩니다.

 

처음에 이해하기가 꽤나 힘들었습니다,, 문자열 관련 알고리즘은 역시 어려운 것 같습니다.

 

다음은 코드입니다.

 

#include <bits/stdc++.h>

using namespace std;

string str;
string astr;
int palin[200010];


void manachers() {

    //maxlen 은 위치+펠린드롬의 길이가 가장 긴 값 cur은 그때의 위치 인덱스
    int maxlen = 0, cur = 0;
    int len = astr.size();

    for(int i = 0; i < len; i++) {

        //현재 위치가 maxlen에 포함된 경우
        if(i <= maxlen) palin[i] = min(palin[2*cur-i], maxlen-i);
        else palin[i] = 0;

        int left = i-palin[i]-1;
        int right = i+palin[i]+1;
        while(left >= 0 && right < len && astr[left] == astr[right]) {
            palin[i]++;
            left = i-palin[i]-1;
            right = i+palin[i]+1;
        }

        if(maxlen < i+palin[i]) {
            maxlen = i+palin[i];
            cur = i;
        }
    }
}

int main(void) {
    ios_base::sync_with_stdio(false); cin.tie(NULL);
    cin >> str;

    for(int i = 0; i < str.size(); i++) {
        astr+="#";
        astr+=str[i];
    }
    astr+="#";

    manachers();
    int ans = 0;
    for(int i = 0; i < astr.size(); i++) {
        ans = max(ans, palin[i]);
    }
    cout<<ans;

    return 0;
}
반응형

'백준(Baekjoon) 문제' 카테고리의 다른 글

백준 18809 Gaaaaaaaaaarden  (2) 2020.03.23
백준 18808 스티커 붙이기  (0) 2020.03.23
백준 1786 찾기  (0) 2020.03.21
백준 11401 이항계수 3  (0) 2020.03.12
백준 1708 볼록 껍질  (0) 2020.02.13