zoukankan      html  css  js  c++  java
  • [LeetCode-JAVA] 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".

    题意:在原字符串的前面加上若干字母,使其形成回文,返回其中最短的。

    思路1:最开始的思路,总后往前扫面,如果[o - i]可以形成回文,则将n后面的reverse并且添加到s的前面即可,这样做勉强可以AC,但显然是最差的算法。

    代码1(AC时间850ms左右):

    public class Solution {
        public String shortestPalindrome(String s) {
            for(int i=s.length();i>=1;i--)
                if(isPalindrome(s.substring(0, i)))
                    return new StringBuilder(s.substring(i)).reverse()+s;
            return "";
        }
        static boolean isPalindrome(String s){
            int left=0,right=s.length()-1;
            while(left<right)
                if(s.charAt(left++)!=s.charAt(right--))
                    return false;
            return true;
        }
    }

    思路2:和思路1差不太多,考虑是否可以用不同的方式进行判断,只是判断回文的方式不同,采取中心点的方式,可以作为一种想法,但效果和1差不多。

    代码2(AC时间800ms左右):

    public class Solution {
        public String shortestPalindrome(String s) {
            if(s == null || s.length() < 2)
                return s;
            int index = 0;
            for(int i = 0 ; i < s.length()*2-1 ; i++){
                int left = i/2;
                int right = i/2;
                if(i%2 == 1)
                    right++;
                if(helper(s, left, right)){
                    index = (i%2 == 1 ? right*2 : right*2+1);
                }
            }
            
            return new StringBuilder(s.substring(index)).reverse() + s;
        }
        
        private boolean helper(String s, int left, int right) {
            while(left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)){
                left--;
                right++;
            }
            if(left == -1)
                return true;
            return false;
        } 
    }

    思路3(推荐思路):利用曼彻斯特算法,其中利用dp来保存已有的结果,进行大幅度的加速。

    在曼彻斯特回文判断中,加入判断,因为题目最主要是要找到包含第一个字符的回文,因此在循环的过程中,当最长子回文包含第一个字符的时候,将索引更新,最后将回文后面的部分reverse之后添加到s前面即可。

    代码3(AC时间300ms左右):

    public class Solution {
        public String shortestPalindrome(String s) {
            if(s == null || s.length() < 2)
                return s;
            int len = s.length();
            int n = len * 2 + 3;
            char[] toCharry = new char[n];
            toCharry[0] = '$';
            toCharry[1] = '#';
            for(int i = 0 ; i < s.length() ; i++){
                toCharry[2*i + 2] = s.charAt(i);
                toCharry[2*i + 3] = '#';
            }
            toCharry[n-1] = '!';
            
            int[] p = new int[n];
            
            int in = 0;
            int mx = 0;
            int maxpi = 0;
            int maxin = 0;
            
            for(int i = 1 ; i < n-1 ; i++){
                if(i < mx)
                    p[i] = Math.min(mx - i, p[2*in - i]);
                else
                    p[i] = 1;
                while(toCharry[i + p[i]] == toCharry[i - p[i]]) p[i]++;
                if(p[i] + i > mx){
                    mx = i + p[i];
                    in = i;
                }
                if(p[i] > maxpi && in == p[in]){
                    maxpi = p[i];
                    maxin = in;
                }
            }
            StringBuilder sb = new StringBuilder();
            for(int i = maxin+p[maxin] ; i < n-1 ; i += 2){
                sb.append(toCharry[i]);
            }
            
            return sb.reverse() + s;
        }
    }

    参考链接:http://www.felix021.com/blog/read.php?2040

           http://m.blog.csdn.net/blog/xc889078/10858041

  • 相关阅读:
    Java POI 导出EXCEL经典实现 Java导出Excel
    Sublime Text 3 相关
    phonegap 4.2 环境搭建 及 项目创建 运行
    Js 简单分页(一)
    VC调试闪退解决办法
    查找一个数中1的个数
    居中详解
    解决ajax跨域请求 (总结)
    js实现css3的过渡,需要注意的一点(浏览器优化)
    reflow和repaint(摘录自张鑫旭的翻译)
  • 原文地址:https://www.cnblogs.com/TinyBobo/p/4587142.html
Copyright © 2011-2022 走看看