Longest Palindromic Substring

来源:互联网 发布:毕业去向地图制作软件 编辑:程序博客网 时间:2024/06/04 23:29

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

思路:Palindrome分奇数和偶数个,像aba, abba。这里的方法叫做中间生长法,从中间开始,i,j向两边扩展,如果相同继续,否则return,这样来算,O(n^2)的复杂度。

2N-1个center。为什么有2n-1个中心,是因为,每个字符可以做中心,这个没什么问题,那么abba的中心就是两个b之间的空字符串,这样当你生长的时候,要以bb为起点开始两边生长,这样的话,每次都以空字符串生长,这样是n-1个。

注意最后需要用s.substring(start+1,end),因为循环最后已经对start和end进行了--和++的操作。

找中心点的操作就是:扫两遍,分别以 (i,i)  (i,i+1)为左右指针,开始扫描,找对称的string,然后更新。

public class Solution {    public String longestPalindrome(String s) {        if(s == null) return null;        if(s.length() == 1) return s;                String longest = s.substring(0,1);        for(int i = 0; i< s.length(); i++){            String oddStr = findlonger(s,i,i);            if(oddStr.length()> longest.length()){                longest = oddStr;            }        }                for( int i =0; i< s.length(); i++){            String evenStr = findlonger(s,i,i+1);            if(evenStr.length()>longest.length()){                longest = evenStr;            }        }        return longest;    }        public String findlonger(String s, int start, int end){        while(start>=0 && end <s.length() && s.charAt(start) == s.charAt(end)){            start--;             end++;        }        return s.substring(start+1,end);    }}

此题同时可以用dp来做。我觉得此题的突破点就在于dp的矩阵表示的物理意义是什么。这点抓住了,其实这题就出来了。

dp[i][j] 表示的物理意义是:string s里面i到j之间的string是否是palindrome. 那么很自然的会推导出递推关系:

if s(i) != s(j) 直接 dp[i][j] = false;

if s(i) == s(j)  : 

      if( j-i<=2) dp[i][j] = true;

      else dp[i][j] = dp[i+1][j-1]  代表i,j指针向中间移动;

因为计算dp[i][j] 需要用到下一层的dp[i+1][j-1],所以for循环的时候,要从下开始算,也就是从后面开始计算;

public class Solution {    public String longestPalindrome(String s) {       if(s == null || s.length() == 0) return s;       boolean[][] dp = new boolean[s.length()][s.length()];       int start = 0;       int end = 0;       int maxlen = 0;       for(int i=s.length()-1; i>=0; i--){           for(int j=s.length()-1; j>=i; j--){               if(s.charAt(i) != s.charAt(j)){                   dp[i][j] = false;               } else { // s.charAt(i) == s.charAt(j);                   if(j-i <=2 || dp[i+1][j-1]){                       dp[i][j]=true;                       if(maxlen < j-i+1){                           start = i;                           end = j;                           maxlen = j-i+1;                       }                   }               }           }       }       return s.substring(start, end+1);    }}
思路3:还有个思路就是:manacher's algorithm: http://cs-cjl.com/2016/06_27_leetcode_5_longest_palindromic_substring

这个应该是最快的,但是我觉得面试中很难你会发明一种算法,所以我觉得做到以上的解法就够了。有时间了解一下。


0 0
原创粉丝点击