题目地址:
中文:https://leetcode-cn.com/problems/longest-palindromic-substring/
英文:https://leetcode.com/problems/longest-palindromic-substring/
题目描述:
Given a string s, return the longest palindromic substring in s.
Example 1:
Input: s = “babad”
Output: “bab”
Note: “aba” is also a valid answer.
Example 2:
Input: s = “cbbd”
Output: “bb”
Example 3:
Input: s = “a”
Output: “a”
Example 4:
Input: s = “ac”
Output: “a”
Constraints:
1 <= s.length <= 1000
s consist of only digits and English letters (lower-case and/or upper-case),
思路:
思路1:暴力,会超时
列举所有子串,挨个判断。
列举所有字串要O(n^2)的复杂度(见题解1,是n(n-1)/2)。
然后对每个字串进行回文判断是个O(n)的。
所以最终是O(n^3)的复杂度。
思路2:优化暴力
上述暴力方法虽然会超时,但是可以进行优化。在暴力过程中,比如“cbabc”,在计算过“bab”是回文串之后,遍历到“cbabc”仍会进行一遍完整的比对,其中包含了很多重复计算。
思路2就是要利用这些重复计算,使用中心扩散的思想,用一个二维数组dp[i][j]来记录i到j的回文串长度,首先初始化所有i=j的长度为1,初始化相邻的相同字母为dp[i][i+1]=2。
然后,对每个dp[i][j]不为0的情况,以其为中心扩散,判断s[i-1]和s[j+1]是否相同,如果相同的话就继续扩散,这样就避免了重复计算。
结果应该还能优化。。因为时间上我只超过了18%的人。
还有个动规的思路。。待做。。。
题解:
题解1:暴力(不通过)
class Solution {
public static String longestPalindrome(String s) {
int max_cnt = 0;
int temp;
String res = "";
for(int i=0;i<s.length();i++){
for(int j=i+1;j<=s.length();j++){
if(is_back(s.substring(i,j))){
temp = j-i;
if(temp>max_cnt){
res = s.substring(i,j);
max_cnt = temp;
}
}
}
}
return res;
}
public static boolean is_back(String s){
int len = s.length();
for(int i=0;i<len/2;i++)
if(s.charAt(i)!=s.charAt(len-i-1))
return false;
return true;
}
}
题解2:中心扩散AC
class Solution {
public static String longestPalindrome(String s) {
int len = s.length();
int dp[][] = new int[len][len];
int back_len_max = 1;
String back_srt_max = String.valueOf(s.charAt(0));
//下面定义两个初始状态
for(int i=0;i<len;i++)
for(int j=0;j<len;++j)
if(i==j) dp[i][j] = 1;
else dp[i][j] = 0;
for(int i=len-1;i>0;--i) if(s.charAt(i)==s.charAt(i-1)){
dp[i-1][i] = 2;
back_len_max = 2;
back_srt_max = s.substring(i-1,i+1);
}
for(int i=0;i<len;++i)
for(int j=i;j<len;++j)
if(dp[i][j]!=0){
int m = i-1;
int n = j+1;
while(m>=0 && n<len && s.charAt(m)==s.charAt(n)){
if(n-m+1>back_len_max){
back_srt_max = s.substring(m,n+1);
back_len_max = n-m+1;
dp[m][n] = back_len_max;
}
m -= 1;
n += 1;
}
}
return back_srt_max;
}
}