LeetCode 题解(91): 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".

题解:

先制作原字符串的对称镜像字符串,如s = "abcd", 镜像a = "abcddcba"。

然后对新字符串a,按KMP算法求Prefix的方法,求Prefix, 得【0, 0, 0, 0, 0,  0, 0, 1】,然后s.length() - prefix[2 * s.length()-1] 即为需要复制到s前的s尾部字符串的个数。

c++版:

class Solution {
public:
    string shortestPalindrome(string s) {
        string result = "";
        
        if(s.length() == 0)
            return result;
        string a = s + string(s.rbegin(), s.rend());
        vector<int> prefix(2 * s.length());
        for(int i = 1; i < 2 * s.length(); i++) {
            int j = prefix[i-1];
            while(j > 0 && a[i] != a[j])
                j = prefix[j-1];
            if(a[i] == a[j])
                j++;
            prefix[i] = j;
        }
        int count = s.length() - equal[2 * s.length()-1];
        return string(s.rbegin(), s.rbegin() + count) + s;
    }
};


Java 版:

public class Solution {
    public String shortestPalindrome(String s) {
        String result = "";
        if(s.length() == 0)
            return result;
        int[] prefix = new int[s.length() * 2];
        String mirror = s + new StringBuilder(s).reverse().toString();
        for(int i = 1; i < s.length() * 2; i++) {
            int j = prefix[i-1];
            while(mirror.charAt(j) != mirror.charAt(i) && j > 0)
                j = prefix[j-1];
            if(mirror.charAt(i) == mirror.charAt(j))
                prefix[i] = j + 1;
            else
                prefix[i] = 0;
        }
        int count = s.length() - prefix[s.length() * 2 -1];
        result = new StringBuilder(s.substring(s.length()-count, s.length())).reverse().toString() + s;
        return result;
    }
}

Python版:

class Solution:
    # @param {string} s
    # @return {string}
    def shortestPalindrome(self, s):
        result = ""
        if len(s) == 0:
            return result
        s1 = s + s[::-1]
        pre = [0] * len(s1)
        for i in range(1, len(s1)):
            j = pre[i-1]
            while j > 0 and s1[i] != s1[j]:
                j = pre[j-1]
            if s1[i] == s1[j]:
                pre[i] = j + 1
            else:
                pre[i] = 0
                
        count = len(s) - pre[len(s1)-1]
        s2 = s[len(s)-1:len(s)-count-1:-1]
        return s2 + s


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值