LeetCode:最長回文子串【5】
阿新 • • 發佈:2018-09-28
msu 產生 嘗試 ++ 不必要 code 分享 規劃 color
LeetCode:最長回文子串【5】
題目描述
給定一個字符串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為1000。
示例 1:
輸入: "babad" 輸出: "bab" 註意: "aba"也是一個有效答案。
示例 2:
輸入: "cbbd" 輸出: "bb"
題目分析
1.一個常見的錯誤!
有些人會忍不住提出一個快速的解決方案,不幸的是,這個解決方案有缺陷(但是可以很容易地糾正):
反轉 SS,使之變成 S‘S′。找到 SS 和 S‘S′ 之間最長的公共子串,這也必然是最長的回文子串。
這似乎是可行的,讓我們看看下面的一些例子。例如,S=“caba” , S′=“abac”: SS 以及 S‘S′ 之間的最長公共子串為“aba”,恰恰是答案。
讓我們嘗試一下這個例子:S=“abacdfgdcaba” , S′=“abacdgfdcaba”:SS 以及 S‘S′ 之間的最長公共子串為“abacd”,顯然,這不是回文。
2.動態規劃的思路!
為了改進暴力法,我們首先觀察如何避免在驗證回文時進行不必要的重復計算。考慮“ababa” 這個示例。如果我們已經知道 “bab” 是回文,那麽很明顯,“ababa” 一定是回文,因為它的左首字母和右尾字母是相同的。
我們給出P(i,j)的定義如下:
因此有,
這產生了一個直觀的動態規劃解法,我們首先初始化一字母和二字母的回文,然後找到所有三字母回文,並依此類推 …
Java題解
class Solution { public String longestPalindrome(String s) { if(s==null||s.length()==0) return s; String res =""; boolean [][] dp = new boolean[s.length()][s.length()]; int max = 0; for(int j=0;j<s.length();j++) { for(int i=0;i<=j;i++) { if(i==j||((j==i+1)&&s.charAt(i)==s.charAt(j))) dp[i][j]=true; else dp[i][j]=(s.charAt(i)==s.charAt(j))&&(dp[i+1][j-1]); if(dp[i][j]&&j-i+1>max) { max=j-i+1; res = s.substring(i,j+1); } } } return res; } }
LeetCode:最長回文子串【5】