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


Solution:

First reverse the string abcd -> dcba

then compare two strings find the longest substring that is the prefix of s and the suffix of s.reverse()

Shift to match and add together

         abcd

+ dcba

---------------

   dcbabcd


Code:

public class Solution {
    public String shortestPalindrome(String s) {
        String rev = new StringBuilder(s).reverse().toString();
        for(int i = 0 ; i < s.length(); i++){
            if(rev.substring(i).equals(s.substring(0,s.length() - i))){
                return rev.substring(0,i) + s;
            }
        }
        
        return rev + s;
        
    }
}

This will get TLE since it took O(n2) to find the common prefix/suffix.

Using KMP to find the prefix suffix is much faster, taking O(n) time

First we build the string s + "#" + s.reverse().

a b c d # d c b a

and the kmp table should be:

a b c d # d c b a

0 0 0 0 0 0 0 0 1

return dcbabcd

the number in the table means the length of the common prefix/suffix ends at that position


Another example

a  a  c  e  c  a  a  a  #  a  a  a  c  e  c  a  a

0  1  0  0  0  1  2  2  0  1  2  2  3  4  5  6  7

so the anwser is a + a  a  c  e  c  a  a  a = aaacecaaa


How to compute this table?

public int[] computeKMP(String p){
        int[] ret = new int[p.length()];
        int j = 0;
        int i = 1;
        while(i < p.length()){
            if(p.charAt(j) == p.charAt(i)){
                ret[i] = j + 1;
                j++;
                i++;
            } else {
                if(j == 0){
                    ret[i] = 0;
                    i++;
                } else{
                    j = ret[j - 1];
                }
            }
        }
        return ret;
    }

And the code:

public String shortestPalindrome(String s) {
        String rev = new StringBuilder(s).reverse().toString();
        String p = s + "#" + rev;
        int[] kmp = computeKMP(p);
        int len = kmp[kmp.length - 1];
        
        return new StringBuilder(s.substring(len)).reverse().toString() + s;
        
}












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值