Shortest Palindrome -- leetcode

来源:互联网 发布:如何实现数组的排序 编辑:程序博客网 时间:2024/05/13 12:15

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".



算法一:

先找出字符串S最大的回文串,该回文串的特点,左边界与S左边界同。

故问题转化为,求出该回文串的右边界。

然后将右边界后面的字符反转加到S前面,即为题目所求。


由于回文串的特点为,反转后,得到的新串与原串相等。 

则将S串,整体反转后得到一个新串RS。

则题目进一步转化为,求S串的最大前缀,且该前缀与RS的后缀相等。


在leetcode上实际执行时间为96ms。

class Solution {public:    string shortestPalindrome(string s) {        string rev(s.rbegin(), s.rend());        int size = s.size();        for (; size > 0; --size) {            if (s.substr(0, size) == rev.substr(rev.size()-size, size))                break;        }        return rev.substr(0, rev.size()-size) + s;    }};


算法二,KMP前缀法

算法一,其实不够效率。

求出最大的 前缀且与后缀相等,可以寻求KMP帮助。

KMP建立next数组过程,就是一个不断求出当前子串中,最大的前缀和后缀相等问题。

这里,我们S字符串,和其反转后得到新字符串RS,并在中间加入一个分隔字符,合并成一个新的字符串。从而问题就可以用KMP方法解决。

之所以加入分隔字符,是为了防止前缀和后缀有重叠部分。

此处,我们所感兴趣的next数组中最后一个值。

即,合并后的新串中,最大前缀与后缀的长度。


在leetcode上实际执行时间为16ms。远好于算法一。


class Solution {public:    string shortestPalindrome(string s) {        if (s.empty()) return s;        string kmp = s + "#" + string(s.rbegin(), s.rend());        vector<int> next(kmp.size()+1);        int j = -1;        next[0] = j;        for (int i=0; i<kmp.size();) {            while (j>=0 && kmp[i]!=kmp[j])                j = next[j];                        ++i;            ++j;            next[i] = j;        }        string suffix = s.substr(next.back());        return string(suffix.rbegin(), suffix.rend()) + s;    }};



0 0
原创粉丝点击