Question:
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"
//思路 1
找最大回文子串,首先最朴素的、最容易想到的是对回文字符串两侧遍历,这是一个O(n3)方法,但是在Leetcode中一般时间复杂度超过O(n3)的算法是会TLE的
class Solution {
//O(n3)算法
public String longestPalindrome(String s) {
if(s.equals("")) return "";
int maxLength = 0;
String ans = new String("");
for(int i=0;i<s.length();i++){
for(int j=s.length()-1;j>i;j--){
if(maxLength > j-i+1) break;
if(!(s.charAt(i)==(s.charAt(j)))) continue;
System.out.println(j);
int t_i = i+1,t_j = j-1;
while(t_i<t_j){
if(!(s.charAt(t_i)==(s.charAt(t_j)))) break;
t_i = t_i + 1;
t_j = t_j - 1;
}
if(t_i<t_j) continue;
maxLength = j-i+1;
ans = s.substring(i,j+1);
break;
}
}
if(maxLength != 0) return ans;
return s.substring(0,1);
}
}
提交之后果然TLE了。
//思路2
稍加变通,以回文字符串的中心为遍历节点,可以得到一个O(n2)算法
class Solution {
public String longestPalindrome(String s) {
if(s.equals("")) return "";
int max_l = -1;
int max_r = -1;
int final_i = -1;
for(int i=0;i<s.length();i++){
int l_i = 0;
int r_i = 0;
int flag = 0;
while((i-l_i)>=0 && (i+r_i)<=s.length()-1){
if(s.charAt(i)==s.charAt(i+r_i) && flag == 0){
r_i++; continue;
}
if(s.charAt(i)==s.charAt(i-l_i) && flag == 0){
l_i++; continue;
}
//中心节点两侧不等
if(!(s.charAt(i-l_i)==s.charAt(i+r_i))) break;
flag = 1;
l_i++;
r_i++;
}
if((i+r_i)==s.length() && flag == 0) l_i++;
if(r_i + l_i > max_r + max_l){
max_r = r_i;
max_l = l_i;
final_i = i;
}
if(max_r - max_l + 1 >s.length()-1) break;
}
return s.substring(final_i - (max_l-1), final_i + (max_r));
}
}
成功通过测试,运行时间23ms,击败65%的提交。
最后贴上一个击败99.9%提交的6ms的代码,与我自己想的思路大致相同,不过细节做了很多优化,形式还比我写的简洁不少。所以说自己还是图样图森破,还要多学习一个啊。
public class Solution {
int len = 0, maxLength = 0, init = 0;
public String longestPalindrome(String s) {
char[] chars = s.toCharArray();
len = s.length();
if (len <= 1) return s;
for (int i = 0; i < len; i++) {
i = manacher(chars, i);
}
return s.substring(init, init + maxLength);
}
public int manacher(char[] chars, int k) {
int i = k - 1, j = k;
while (j < len - 1 && chars[j] == chars[j + 1]) j++;
int nextCenter = j++;
while (i >= 0 && j < len && chars[i] == chars[j]) {
i--;
j++;
}
if (j - i - 1 > maxLength) {
maxLength = j - i - 1;
init = i + 1;
}
return nextCenter;
}
}