• 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;
        }
    };
  • 相关阅读:
    封装好的AFN网络请求框架和MBProgress
    iOS定时器的使用
    iOS去除导航栏和tabbar的1px横线
    移动端加解密
    改变字符串中部分字符传的字体大小和颜色
    关于NSLog
    ipad开发:二维码扫描,摄像头旋转角度问题解决办法
    iOS-图文表并茂,手把手教你GCD
    计算富文本的高度
    jsp打印
  • 原文地址:https://www.cnblogs.com/lailailai/p/4575362.html
Copyright © 2020-2023  润新知