코딩 테스트 및 알고리즘/leetcode for google

leetcode hard : Shortest Palindrome

띠리링구 2023. 1. 21. 03:16

https://leetcode.com/problems/shortest-palindrome/description/

 

Shortest Palindrome - LeetCode

Shortest Palindrome - You are given a string s. You can convert s to a palindrome by adding characters in front of it. Return the shortest palindrome you can find by performing this transformation.   Example 1: Input: s = "aacecaaa" Output: "aaacecaaa" Ex

leetcode.com

 

이건 어려워서 솔루션 보고 학습을 진행했다.

일단 이 포스팅에서 KMP알고리즘은 설명하지 않을건데 (나도 너무 어렵다 이건)

나도 kmp는 아직 잘 모르기 때문이다. 얼추 이해하긴 했는데 아직 완벽히는 모르겠다.

KMP 공부 참고자료

https://www.youtube.com/watch?v=UcjK_k5PLHI 

https://www.youtube.com/watch?v=yWWbLrV4PZ8 

 

그럼 Official Solution을 보고 학습을 해보자.

 

Approach 1 : Brute force [Time Limit Exceeded]

1. 문자열의 왼쪽에서 가장 큰 회문을 찾는다.

2. 찾은 회문을 제외하고 남은 오른쪽 파트를 뒤집는다.

 

Example

문자열 abac

* 왼쪽에서 찾은 가장 큰 회문 [aba]c => aba

* 찾은 회문 제외한 오른쪽 파트 aba[c] => c

* 앞에 c를 붙이면 회문이 된다. => cabac

 

Algorithm

1. 문자열을 뒤집는다. 이걸 r이라고 하자.

2. 문자열의 길이를 n이라고 하자.

3. 원본 문자열은 s다.

4. s[0:n-i] == r[i:]가 성립될때까지 i를 증가시킨다.

- 즉 처음엔 전체를 뒤집었을때 회문이 되는지 보는거고

- i가 증가함에 따라 맨 오른쪽에서 글자를 하나씩 제거하면서 그걸 뒤집은걸 비교하는거라고 봐도 된다.

5. i를 찾으면 r[:i]에 s를 붙여 리턴한다.

 

class Solution {
public:
    string shortestPalindrome(string s) {
        int n = s.size();
        string rev(s);
        reverse(rev.begin(), rev.end());
        for (int i = 0; i < n; i++) {
            if (s.substr(0, n - i) == rev.substr(i))
                return rev.substr(0, i) + s;
        }
        return "";
    }
};

 

Approach 2 : Two pointers and recursion [Accepted]

* i = 0

* j를 n-1 -> 0으로 iteration

  * s[i] == s[j]면 i++

* loop이 끝나고나면 s[:i]에 palindrome이 포함되어 있다.

* reversed(s[i:]) + recursion(s[:i]) + s[i:]가 정답

최상의 케이스는 s자체가 palindrome일때

최악은 "aababababababa" 이런경우

 

class Solution {
public:
    string shortestPalindrome(string s) {
        int n = s.size();
        int i = 0;
        for (int j = n - 1; j >= 0; j--) {
            if (s[i] == s[j])
                i++;
        }
        if (i == n) {
            return s;
        }
        string remain_rev = s.substr(i, n);
        reverse(remain_rev.begin(), remain_rev.end());
        return remain_rev + shortestPalindrome(s.substr(0, i)) + s.substr(i);
    }
};

 

복잡도

시간 : 최약의 경우 O(N^2)

공간 : O(N)

 

아 어렵다 세상에 똑똑이형들 너무많당