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:
Input: "cbbd"
Output: "bb"
思路一:求每一個子串,但是要知道一個技巧就是如何截取從最大串到最小串的判斷。時間複雜度是O(N^3)
class Solution {
public String longestPalindrome(String s) {
//O(N^3)的時間複雜度
if(s.length() <= 1)
return s;
for(int i = s.length(); i >= 0; i--)
{
for(int j = 0; j <= s.length() - i; j++)
{
//關鍵在於這個截取的子串,由長到短,這個是最關鍵的
String subStr = s.substring(j, i+j);//從外向內收縮的子串,截取的子串越來越短
int count = 0;
for(int k = 0; k < subStr.length()/2; k++)
{
if(subStr.charAt(k) == subStr.charAt(subStr.length() - k -1))//判斷是不是迴文
count++;
}
if(count == subStr.length() / 2)//第一次出現的迴文就是最長的
return subStr;
}
}
return "";
}
}
思路二:馬拉車算法,時間複雜度爲O(N),具體算法過程看這裏:Manacher’s Algorithm 馬拉車算法
class Solution {
public String longestPalindrome(String s) {
//馬拉車算法O(N)的時間複雜度
if(s.length()==0)
return "";
StringBuilder t = new StringBuilder("$#");
for(int i = 0; i < s.length(); i++)
{
t.append(s.charAt(i));
t.append('#');
}
t.append('@');
int[] p = new int[t.length()];
int mx = 0;
int id = 0;
int resLen = 0;
int resCenter = 0;
for(int i = 1; i < t.length()-1; ++i)
{
//關鍵算法步驟
p[i] = mx > i ? Math.min(p[2 * id - i], mx - i) : 1;
//如果對稱點的長度比當前的還長,後面的是否匹配要自己去算
while (((i - p[i])>=0) && ((i + p[i])<t.length()-1)
&& (t.charAt(i + p[i]) == t.charAt(i - p[i])))
++p[i];
if (mx - i < p[i]) {
mx = i + p[i];
id = i;
}
if (resLen < p[i]) {
resLen = p[i];
resCenter = i;
}
}
return s.substring((resCenter - resLen) / 2,(resCenter - resLen) / 2 + resLen - 1);
}
}