Given a string s, find the longest palindromic substring in s. You may
assume that the maximum length of s is 1000.Example 1:算法
Input: "babad" Output: "bab" Note: "aba" is also a valid answer.
Example 2:appInput: "cbbd" Output: "bb"ui
1.第一思路是dp問題,不過對於一階dp找不到對應關係,能夠經過二階dp解決
i<=j的狀況下dpi是否是迴文數有幾種狀況
i==j ||
s[i]==s[j] && (dpi+1 || i==j+1)code
public String longestPalindrome(String s) { int l=s.length(); if(l<=0) return s; int left=1; int right=1; int[][] dp=new int[l+1][l+1]; for(int i=l;i>=1;i--){ for(int j=i;j<=l;j++){ if(i==j || (s.charAt(i-1)==s.charAt(j-1) && (dp[i+1][j-1]==1 || j==i+1))){ dp[i][j]=1; if(right-left<j-i){ left=i; right=j; } } } } return s.substring(left-1,right); }
2.第二組思路能夠對每一個字符作匹配string
public String longestPalindrome(String s) { int l=s.length(); if(l<=0) return s; int left=0; int right=0; char[] array=s.toCharArray(); for(int i=0;i<array.length;i++){ int j=0; do{ j++; }while(i-j>=0 && i+j<l && array[i-j]==array[i+j]); j--; if(2*j+1>=right-left+1){ left=i-j; right=i+j; } } for(int i=0;i<array.length-1;i++){ if(array[i]!=array[i+1]) continue; int j=0; do{ j++; }while(i-j>=0 && i+j+1<l && array[i-j]==array[i+j+1]); j--; if(2*j+2>right-left+1){ left=i-j; right=i+j+1; } } return s.substring(left,right+1); }
3.而後是一個正常人想不到的思路,就是馬拉車算法,他其實和2算法很類似,他解決了兩個問題,一個是將兩種迴文狀況經過改變初始數據變爲一種,而是在求某個字符的狀況下拿到以前已知的結果。im
public String longestPalindrome(String s) { int l=s.length(); if(l<=0) return s; int left=0; int right=0; StringBuilder builder=new StringBuilder("#"); char[] array=s.toCharArray(); for(char c:array){ builder.append(c); builder.append('#'); } for(int i=0;i<array.length;i++){ int j=0; do{ j++; }while(i-j>=0 && i+j<l && array[i-j]==array[i+j]); j--; if(2*j+1>=right-left+1){ left=i-j; right=i+j; } } left=(left+1)/2; right=(right-1)/2; return s.substring(left,right+1); }
-mx 123 -i 321 id 123 i 321 mx
id表明能到達最右側迴文串的中心點
mx表明半徑
在-mx到mx內,串必定是對稱的
因此i點最小的半徑爲Math.min(mx-i,r[-i])數據
public String longestPalindrome(String s) { int l=s.length(); if(l<=0) return s; int left=0; int right=0; StringBuilder builder=new StringBuilder("#"); char[] array=s.toCharArray(); for(char c:array){ builder.append(c); builder.append('#'); } array=builder.toString().toCharArray(); int[] r=new int[array.length]; int mx=0; int id=0; for(int i=0;i<array.length;i++){ int j=0; if(mx>i){ j=Math.min(mx-i,r[2*id-i]); } do{ j++; }while(i-j>=0 && i+j<array.length && array[i-j]==array[i+j]); j--; r[i]=j; if(i+j>mx) { mx=i+j; id=i; } if(2*j+1>=right-left+1){ left=i-j; right=i+j; } } left=(left+1)/2; right=(right-1)/2; return s.substring(left,right+1); }