标签:
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