214. Shortest Palindrome (Hard)

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

Solution 1: KMP

KMP(Knuth-Morris-Pratt)

这道题让我们求最短的回文串,LeetCode中关于回文串的其他的题目有 Palindrome Number 验证回文数字, Validate Palindrome 验证回文字符串, Palindrome Partitioning 拆分回文串,Palindrome Partitioning II 拆分回文串之二和 Longest Palindromic Substring 最长回文串。题目让我们在给定字符串s的前面加上最少个字符,使之变成回文串,那么我们来看题目中给的两个例子,最坏的情况下是s中没有相同的字符,那么最小需要添加字符的个数为s.size() - 1个,第一个例子的字符串包含一个回文串,只需再在前面添加一个字符即可,还有一点需要注意的是,前面添加的字符串都是从s的末尾开始,一位一位往前添加的,那么我们只需要知道从s末尾开始需要添加到前面的个数。这道题如果用brute force无法通过OJ,所以我们需要用一些比较巧妙的方法来解。这里我们用到了KMP算法,KMP算法是一种专门用来匹配字符串的高效的算法,具体方法可以参见这篇博文从头到尾彻底理解KMP。我们把s和其转置r连接起来,中间加上一个其他字符,形成一个新的字符串t,我们还需要一个和t长度相同的一位数组next,其中next[i]表示从t[i]到开头的子串的相同前缀后缀的个数,具体可参考KMP算法中解释。最后我们把不相同的个数对应的字符串添加到s之前即可,代码如下:

string shortestPalindrome(string s) {
    string s2 = s;
    reverse(s2.begin(), s2.end()); // reverse string
    string p = s+"#"+s2; // pattern
    int j = 0, n = p.size();
    int next[n]; next[0] = 0; // KMP
    for (int i = 1; i < p.size(); ++i) {
        while (j > 0 && p[j] != p[i]) j = next[j-1];
        if (p[j] == p[i]) ++j;
        next[i] = j;
    }
    return s2.substr(0, s2.size()-next[n-1])+s;
}

results matching ""

    No results matching ""