【Leetcode】Shortest Palindrome

题目链接: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;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值