leetcode 214. 最短迴文串 解題報告

給定一個字符串 s,你能夠經過在字符串前面添加字符將其轉換爲迴文串。找到並返回能夠用這種方式轉換的最短迴文串。python

示例 1:ios

輸入: "aacecaaa"
輸出: "aaacecaaa"

示例 2:c++

輸入: "abcd"
輸出: "dcbabcd"

解題思路一

直覺告訴咱們,咱們找出左邊的最長迴文子串,好比aacecaaa左側最長的迴文子串就是aacecaa,而後將右側剩餘的部分反轉補到原串的左側便可。因爲找的是最長的迴文子串,直接從右往左,找到第一個迴文子串便可。對應的代碼以下所示數組

class Solution:
    def shortestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        r = 1
        for i in range(len(s), 0, -1):
            if s[0:i] == (s[0:i])[::-1]:
                r = i
                break
        
        return (s[r:])[::-1] + s

解題思路二

第二種思路相較於第一種思路更爲巧妙,利用到了KMP中的fail數組,也有人叫作next數組。spa

由於fail數組中記錄了最短回退位置,也即保證了回退後所匹配的部分是最長的。咱們直接將原串和反轉的原串拼在一塊兒,求出其fail數組,最後的位置可以回退到的位置即爲左側最長的迴文子串。code

#include<bits/stdc++.h>

using namespace std;

static auto x = []() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(NULL);
    return 0;
}
();


const int maxn = 100010;
int fail[maxn];

class Solution {
public:
    string shortestPalindrome(string s) {
        string t(s);
        reverse(t.begin(), t.end());
        string st = s + "#" + t;
        int sz = st.size();
        for(int i = 0,j = fail[0] = -1; i < sz; ++i) {
            while(j != -1 && st[i] != st[j])
                j = fail[j];
            fail[i + 1] = ++j;
            if(st[i + 1] == st[j])
                fail[i+1] = fail[j];
        }
        return t.substr(0, t.size()-fail[sz]) + s;
    }
};

int main() {

    return 0;
}
相關文章
相關標籤/搜索