【Leetcode】Shortest Palindrome

来源:互联网 发布:js改变当前url 不跳转 编辑:程序博客网 时间:2024/06/07 14:34

题目链接:https://leetcode.com/problems/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”.

思路:
这题老是超时。。看了discuss,有个代码很惊艳,我将试着说清对这段代码的理解。
题意是 在字符串 s 前面加最少的字符串 c 使得 整个字符串是回文串。
我们可以将原字符串 简化为A+B的结构,A是 s 从头开始的最长回文子串。那么只需在s前面加上B的逆转字符串 D 就可以使得 D+S=D+A+B为回文串了。 所以关键在于如何找到下标 i 使得0~i的字符串为s的从头开始的最长回文子串。naive的方法是遍历 s.length种可能,对每种可能的(0~i) A都判断是否是回文,时间复杂度为O(n^2),会超时。
我们可以尽可能的确定B,哪怕是B的一段后部分,代码:if(s.charAt(i)==s.charAt(j)) j++; 可以让 0~j-1的字符串绝对包括回文串(可能回文串后面会接非回文字符串),剩下的j~s.length部分字符串绝不会是回文串的一部分,所以可以把j~s.length作为B的一部分添加到A的前面,然后递归处理A+前部分B。
最后解释一下上述黑体字部分。可以理解为 j在 A+B的结构上从0开始遍历,i在A+B的结构从尾部开始遍历,因为B字符串可能包括一些A字符串中的字符,导致 j 最后会停在B段中间某位置,所以 s[j:]绝不会是回文。 s[0:j]一定包括是回文。

算法:

    public String shortestPalindrome(String s) {        int j=0;        for(int i=s.length()-1;i>=0;i--){            if(s.charAt(i)==s.charAt(j))                j++;        }        if(j==s.length())            return s;        String suffix = s.substring(j);        return new StringBuilder(suffix).reverse().toString()+shortestPalindrome(s.substring(0, j))+suffix;    }
0 0
原创粉丝点击