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

    题解:

    求s前缀和 reverse s 后缀最长重合.

    Time Complexity: O(n ^ 2).

    Space: O(n).

    AC Java:

     1 class Solution {
     2     public String shortestPalindrome(String s) {
     3         if(s == null || s.length() == 0){
     4             return s;
     5         }
     6         
     7         int n = s.length();
     8         String rev = new StringBuilder(s).reverse().toString();
     9         for(int i = 0; i < n; i++){
    10             if(s.substring(0, n - i).equals(rev.substring(i))){
    11                 return rev.substring(0, i) + s;
    12             }
    13         }
    14         
    15         return rev + s;
    16     }
    17 }
    其实求最短回文串,其实可以看作两个字符串求两串中的最长匹配字符,比如 串 “ abcd”
    • 注意,由于这里一个串可以是回文串,所以此处的前缀和后缀应该分别加上最后一个和第一个字符
    就是求“abcd”和反串”dcba“的前缀和后缀最大匹配长度
    原始串 前缀 反转串 后缀 最大匹配
    abcd a ab abc abcd dcba a ba cba dcba a

    由上面可以看出,abcd和dcba的最长匹配为a,一个字符,那么最后的回文串就是 反转串的长度4减去匹配长度1,得到3, 即反转串的前三个字符加上 原始串组成 ”abcabcd“

    KMP算法中曾今和相似的利用过最大前缀和后缀求next[]数组,如果我们这样看 将原始串S和反转串R形成一个新串New
    S+#+反转   =  abcd#dcba 

    Note: 这里之所以要加上#是为了防止p[New.length()-1]的值要大于s.length().

    另外需要注意如下例子,产生了aabba, 如果不加"#", 前面和反转相加正好产生了一个很长的palindrome.

    Input:"aabba"
    Output:"aabba"
    Expected:"abbaabba"
    另外最后要加空格是因为next 把标记右移了一位,加空格是为了让这一位显现出来。
    Time Complexity: O(n). Space: O(n).

    AC Java:

     1 public class Solution {
     2     public String shortestPalindrome(String s) {
     3         if(s == null || s.length() <=1){
     4             return s;
     5         }
     6         StringBuilder rev = new StringBuilder(s);
     7         //add "#" 为了防止next后面的数字大于 s的长度,并且s本身能和后面产生palindrome, 如"aabba"
     8         String mirror = s  + "#" + rev.reverse().toString() + " ";
     9         int [] next = new int[mirror.length()];
    10         getNext(mirror,next);
    11         StringBuilder res = new StringBuilder(s.substring(next[next.length-1]));
    12         return res.reverse().toString() + s;
    13     }
    14     private void getNext(String s, int [] next){
    15         next[0] = -1;
    16         int k = -1; 
    17         int j = 0;
    18         while(j<s.length()-1){
    19             if(k==-1 || s.charAt(k) == s.charAt(j)){
    20                 k++;
    21                 j++;
    22                 next[j] = k;
    23             }else{
    24                 k=next[k];
    25             }
    26         }
    27     }
    28 }

    类似Implement strStr().

    参考了这篇帖子:http://blog.csdn.net/yujin753/article/details/47047155

  • 相关阅读:
    ASP.NET从字符串中查找字符出现次数的方法
    2009最新Godaddy域名Push教程(GODADDY域名转移会员号)
    jQueryJSON 无刷新三级联动
    select scope_identity()
    BugTracker.NET安装指南
    这道面试必问的JVM面试题70%的Java程序员会做错
    想要金九银十面试通关,不懂 Java多线程肯定是不行的!
    一线互联网公司Redis使用精髓,你必须要掌握这4点!
    5种JVM垃圾收集器特点和8种JVM内存溢出原因
    一次性集中处理大量数据的定时任务,如何缩短执行时间?
  • 原文地址:https://www.cnblogs.com/Dylan-Java-NYC/p/4924389.html
Copyright © 2011-2022 走看看