链表算法题(程序员面试宝典)
解题思路主要来源于leetcode官方与《程序员面试宝典》。
5. 最长回文子串
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”
解题方法
参考资料1:https://mp.weixin.qq.com/s?__biz=MzAxODQxMDM0Mw==&mid=2247484471&idx=1&sn=7c26d04a1f035770920d31377a1ebd42&chksm=9bd7fa3faca07329189e9e8b51e1a665166946b66b8e8978299ba96d5f2c0d3eafa7db08b681&scene=21#wechat_redirect
参考资料2:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zhong-xin-kuo-san-dong-tai-gui-hua-by-liweiwei1419/
解题思路1
中心扩散找回文子串
class Solution {
public String longestPalindrome(String s) {
//保存最长的回文子串
String res = "";
for(int i=0;i<s.length();i++){
//以s[i]为中心的回文串
String s1 = palindrome(s,i,i);
//以s[i] s[i+1] 为中心的回文串
String s2 = palindrome(s,i,i+1);
//选择最大的回文串
res = res.length()>s1.length()?res:s1;
res = res.length()>s2.length()?res:s2;
}
return res;
}
public String palindrome(String s,int l,int r){
//找回文子串,从中间向两边扩散寻找
//防止越界
while(l>=0&&r<s.length()&&s.charAt(l)==s.charAt(r)){
l--;
r++;
}
return s.substring(l+1,r);
}
}
解题思路2
暴力法,枚举所有长度大于等于2的字符串,然后对其进行判别是否为回文串,保留长度最大的回文串即可。
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
if(len<2){
return s;
}
//记录最大回文串长度
int maxLen = 1;
//记录最大回文串长度的起始索引
int index = 0;
//暴力法,枚举大于等于2长度的字符串
for(int i=0;i<s.length()-1;i++){
for(int j=i+1;j<s.length();j++){
if(j-i+1>maxLen&&validPalindrome(s,i,j)){
//如果当前字符串长度 大于 最大回文串长度 且是回文字符串
//更新
maxLen = j-i+1;
index = i;
}
}
}
return s.substring(index,index+maxLen);
}
public boolean validPalindrome(String s,int l,int r){
//找回文子串,从中间向两边扩散寻找
//防止越界
while(l<r){
if(s.charAt(l)!=s.charAt(r)){
return false;
}
l++;
r--;
}
return true;
}
}
解题思路3
动态规划法
class Solution {
public String longestPalindrome(String s) {
//动态规划
int len = s.length();
if(len<2){
return s;
}
//dp[i][j] 代表s[i...j] 是否为回文串
boolean[][] dp = new boolean[len][len];
//记录最大回文串长度
int maxLen = 1;
//记录最大回文串长度的起始索引
int index = 0;
//初始化 dp 对角线即dp[i][i] 代表一个字符串 肯定为回文串
for(int i=0;i<len;i++){
dp[i][i] = true;
}
//动态规划
for(int j=1;j<len;j++){
for(int i=0;i<j;i++){
if(s.charAt(i)!=s.charAt(j)){
//s[i]!=s[j] 即 s[i..j]一定不是回文串
dp[i][j]=false;
}else{
if((j-1)-(i+1)+1<2){
//s[i+1..j-1] 的区间长度小于2
//1. s[i+1..j-1] 的区间长度为1时,可判定其为回文串
//2. s[i+1..j-1] 的区间长度为0时,可判定其为回文串
dp[i][j] = true;
}else{
dp[i][j] = dp[i+1][j-1];
}
}
if(dp[i][j] && j-i+1>maxLen){
//如果当前字符串长度 大于 最大回文串长度 且是回文字符串
//更新
maxLen = j-i+1;
index = i;
}
}
}
return s.substring(index,index+maxLen);
}
}