码迷,mamicode.com
首页 > 其他好文 > 详细

LeetCode 5 -- Longest Palindromic Substring

时间:2015-05-05 23:42:33      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:

Given a string S, find the longest palindromic substring inS. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.


 

第一种方法比较直接,实现起来比较容易理解。基本思路是对于每个子串的中心(可以是一个字符,或者是两个字符的间隙,比如串abc,中心可以是a,b,c,或者是ab的间隙,bc的间隙)往两边同时进行扫描,直到不是回文串为止。假设字符串的长度为n,那么中心的个数为2*n-1(字符作为中心有n个,间隙有n-1个)。对于每个中心往两边扫描的复杂度为O(n),所以时间复杂度为O((2*n-1)*n)=O(n^2),空间复杂度为O(1),代码如下:

 1 package Leetcode;
 2 
 3 //提交时成功的,为什么结果却只是首字母?
 4 
 5 public class LongestPalindromeSubstring {
 6     public static String longestPalindrome(String s) {
 7         if (s == null || s.length() == 0)
 8             return "";
 9         int maxLen = 0;
10         String res = "";
11 
12         for (int i = 0; i < 2*s.length() - 1; i++) {
13              int left = i / 2;
14             int right = i / 2;
15             if (i % 2 == 1)
16                 right++;
17 
18             String str = lengthOfPalindrome(s, left, right);
19 
20             if (str.length() > maxLen) {
21                 res = str;
22                 maxLen = str.length();
23             }
24         }
25         return res;
26     }
27 
28     public static String lengthOfPalindrome(String str, int left, int right) {
29         while (left >= 0 && right < str.length()
30                 && str.charAt(left) == str.charAt(right)) {
31             left--;
32             right++;
33         }
34         return str.substring(left + 1, right);
35     }
36     
37     public static void main(String[] args){
38         String str = "sabcbafds";
39         String res = longestPalindrome(str);
40         System.out.println(res);
41     }
42 
43 }

而第二种方法是用动态规划,思路比较复杂一些,但是实现代码会比较简短。基本思路是外层循环i从后往前扫,内层循环j从i当前字符扫到结尾处。过程中使用的历史信息是从i+1到n之间的任意子串是否是回文已经被记录下来,所以不用重新判断,只需要比较一下头尾字符即可。这种方法使用两层循环,时间复杂度是O(n^2)。而空间上因为需要记录任意子串是否为回文,需要O(n^2)的空间,代码如下:

 1 public String longestPalindrome(String s) {
 2   if(s == null || s.length()==0)
 3     return "";
 4   boolean[][] palin = new boolean[s.length()][s.length()];
 5   String res = "";
 6   int maxLen = 0;
 7   for(int i=s.length()-1;i>=0;i--)
 8   {
 9     for(int j=i;j<s.length();j++)
10     {
11       if(s.charAt(i)==s.charAt(j) && (j-i<=2 || palin[i+1][j-1]))
12       {
13         palin[i][j] = true;
14         if(maxLen<j-i+1)
15         {
16           maxLen=j-i+1;
17           res = s.substring(i,j+1);
18         }
19       }
20     }
21   }
22   return res;
23 }

还有另外一种更简单的方法,复杂度O(n),但没怎么搞懂

参考 http://leetcode.com/2011/11/longest-palindromic-substring-part-ii.html

// Manacher algorithm
 
// Transform S into T
// For example, S = "abba", T = "^#a#b#b#a#$"
// ^ and $ signs are sentinels appended to each string
// to avoid bound checking
string preProcess(string s)
{
  int n = s.length();
  if (n == 0) return "^$";
  string ret = "^";
  for (int i = 0; i < n; ++i)
    ret += "#" + s.substr(i, 1);
  ret += "#$";
  return ret;
}
 
string longestPalindromeManacher(string s)
{
  string T = preProcess(s);
  int n = T.length();
  vector<int> p(n, 0);
  int C = 0, R = 0;
  for (int i = 1; i < n-1; ++i){
    int i_mirror = 2*C-i;
 
    p[i] = (i < R) ? min(R-i, p[i_mirror]) : 0; 
 
    // attempt to expand palindrome centered at i
    while(T[i + 1 + p[i]] == T[i - 1 - p[i]])
      ++ p[i];
 
    // If palindrome centered at i expand past R,
    // adjust center based on expanded palindrome,
    if(p[i] + i > R){
      C = i;
      R = i + p[i];
    }
  }
 
  // Find the maximum element in p
  int maxLen = 0;
  int centerIndex = 0;
  for (int i = 1; i < n-1; ++i){
    if(p[i] > maxLen){
      maxLen = p[i];
      centerIndex = i;
    }
  }
  return s.substr((centerIndex - 1 - maxLen)/2 , maxLen);
}

 

LeetCode 5 -- Longest Palindromic Substring

标签:

原文地址:http://www.cnblogs.com/myshuangwaiwai/p/4480459.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!