##題目 給定一個字串 s,找到 s 中最長的迴文子串。你可以假設 s 長度最長為1000。
示例:
輸入: "babad"
輸出: "bab"
注意: "aba"也是有效答案
複製程式碼
示例:
輸入: "cbbd"
輸出: "bb"
複製程式碼
思路
一開始是想用最笨的方法來解的,也就是找出所有的字串,然後再對所有的子串進行迴文檢測,並記錄長度。這種方式時間複雜度可想而知,O(n)*O(n)*O(n)=O(n^3)。所以這種肯定是不能滿足我們要求的。
ok,那我們來分析一下這個問題,先把這個問題特殊化;
-
假如輸入的字串長度就是1
那麼這個字串的最長迴文串就是它自己,長度就是1
-
假如字串長度為2,它要是迴文串的化,就需要兩個字元是相等的。
即:s[i] == s[j] 且i-j=1(此處假定i是較大索引位置)
-
那麼對於i-j>1的情況下呢?是不是隻要滿足下面的條件就可以了:
即:s[i] == s[j]&&s[i-1] == s[j+1]
其實這種思路就是動態規劃。關於動態規劃的理論性文字就不碼了,有興趣的小夥伴闊以自行學習。下面就針對這個問題碼一下程式碼:
public String longestPalindrome(String s) {
// 長度為1,返回當前串
if (s.length()==1){
return s;
}
//長度為2並且兩個字元相等則返回
if (s.length()==2&&s.charAt(0)==s.charAt(1)){
return s;
}
//用於標記isLongestPalindrome[j][i]即從j到i是否是迴文串;
//如isLongestPalindrome[1][5]==true則表示字串索引位置從1到5的子串是迴文串。
boolean[][] isLongestPalindrome = new boolean[s.length()][s.length()];
//最長迴文串初始最大為0
int maxlen = 0;
//對應的maxlen的開始索引位置
int beginIndex = 0;
//對應的maxlen的結束索引位置
int lastIndex = 0;
for (int i=0;i<s.length();i++){
int j=i;
while(j>=0){
//滿足上述的第三個條件,即當前s.charAt(i)==s.charAt(j)並
//且s[j+1到i-1]也是迴文串
if (s.charAt(i)==s.charAt(j)&&(i-j<2||isLongestPalindrome[j+1][i-1])){
isLongestPalindrome[j][i]=true;
if (maxlen < i-j+1) {
beginIndex = j;
lastIndex = i+1;
maxlen = i-j+1;
}
}
j--;
}
}
return s.substring(beginIndex,lastIndex);
}
複製程式碼