LeetCode Shortest Palindrome

Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. Find and return the shortest palindrome you can find by performing this transformation.

For example:

Given "aacecaaa", return "aaacecaaa".

Given "abcd", return "dcbabcd".

Credits:
Special thanks to @ifanchu for adding this problem and creating all test cases. Thanks to @Freezen for additional test cases.

先来个直接的,就是求出从字符串起始处开始的最长回文串,如果有这样的回文串存在(必然存在,单个字符就是一个回文串,但找到的回文串长度越长,补全后的回文串整体长度就越小),我们只需要以这个找到的回文串为中心,再在字符串前补全即可。但是TLE

class Solution {

public:

    string shortestPalindrome(string s) {

        int len = s.size();

        int idx;

        for (idx=len; idx>0; idx--) {

            if (isPar(s, 0, idx)) {

                break;

            }

        }

        string mirror;

        for (int i=len - 1; i>=idx; i--) {

            mirror.push_back(s[i]);

        }

        return mirror + s;

    }

    

    bool isPar(string& s, int start, int end) {

        int p = start;

        int q = end - 1;

        while (p < q) {

            if (s[p] != s[q]) {

                return false;

            }

            p++, q--;

        }

        return true;

    }

};

一样的思路,别人的就简洁很多 ,92ms

class Solution {

public:

    string shortestPalindrome(string s) {

        string s2=s;

        reverse(s2.begin(),s2.end());

        int n=s.size(),l;

        for(l=n;l>=0;l--)

        {

            if(s.substr(0,l)==s2.substr(n-l))

                break;

        }

        return s2.substr(0,n-l)+s;

    }

};

 

 还是一样的思路,但是加入高效求回文串的过程(manacher's algorithm,见另一篇自己博客图解,网上资料也很多),时间8ms,速度提高太多了

class Solution {

public:

    string shortestPalindrome(string s) {

        string ss("$");

        for (int i=0; i<s.size(); i++) {

            ss.push_back(s[i]);

            ss.push_back('$');

        }

        

        int len = ss.size();

        vector<int> pl(len, 1);

        

        int far = 0;

        int mid = 0;

        int longest = 0;

        int mirror = 0;

        

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

            int cfar = i;

            

            // if this index is covered by exist palindrome

            if (far > i) {

                mirror = 2 * mid - i;

                cfar = min(pl[mirror], far - i) + cfar;

            }

            // spread out

            while (cfar < len && (2 * i - cfar >= 0) && ss[cfar] == ss[2 * i - cfar]) {

                cfar++;

            }

            // current palindrome single part length(incuded middle character)

            pl[i] = cfar - i;

            

            // update right farest index covered by palindrome

            if (cfar > far) {

                mid = i;

                far = cfar;

            }

            // is this palindrome start from s[0]?

            if (2 * i - cfar == -1) {

                // index i in ss is just the palindrome length in s(original string)

                longest = i;

            }

        }

        

        string str = s.substr(longest);

        reverse(str.begin(), str.end());

        

        return str + s;

    }

};

 discuss里还有用KMP做的,不过KMP不熟,以后再写。

改写一下:

class Solution {

public:

    string shortestPalindrome(string s) {

        if (s.size() < 2) {

            return s;

        }

        int plen = palindrome(s);

        string left = s.substr(plen);

        reverse(left.begin(), left.end());

        return left + s;

    }

    

    int palindrome(string& s) {

        string ms(s.size() * 2 + 1, '$');

        int i = 0;

        for (char ch : s) {

            ms[i++ * 2 + 1] = ch;

        }

        int mlen = ms.size();

        vector<int> lens(mlen, 0);

        

        int far = 0;

        int lcenter = 0;

        

        int maxlen = 2;

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

            int p = i, q = i;

            if (i < far) {

                int mirror = 2 * lcenter - i;

                int step = min(lens[mirror], far - i);

                p -= step;

                q += step;

            }

            while (p >= 0 && q < mlen && ms[p] == ms[q]) {

                p--, q++;

            }

            if (q > far) {

                far = q;

                lcenter = i;

            }

            lens[i] = q - i;

            if (p < 0) {

                maxlen = max(maxlen, lens[i]);

            }

        }

        return (maxlen * 2 - 1) / 2;

    }

};

 

你可能感兴趣的:(LeetCode)