大家好!我是曾续缘😅
今天是《LeetCode 热题 100》系列
发车第 93 天
多维动态规划第 3 题
❤️点赞 👍 收藏 ⭐再看,养成习惯
给你一个字符串
s
,找到s
中最长的回文子串。如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
示例 1:
输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。示例 2:
输入:s = "cbbd" 输出:"bb"提示:
难度:💖💖
1 <= s.length <= 1000
s
仅由数字和英文字母组成
解题方法
这道题目要求我们找到一个字符串中最长的回文子串。回文串是指正读和反读都相同的字符串。
- 初始化一个二维布尔数组
f
,其中f[i][j]
表示字符串s
从第i
个字符到第j
个字符的子串是否是回文串。初始时,为了后续方便(主要是[i + 1][j - 1]
),所有f[i][j]
都设为true
,因为后续我们会遍历到每个值,不是回文串的将设置为false
。 - 使用两层循环,外层循环表示子串的长度,从2开始,每次增加1;内层循环表示子串的起始和结束位置。
- 在内层循环中,首先判断子串的结束位置是否超出字符串的长度,如果超出,则跳出内层循环。接着,判断子串的两个端点字符是否相等,如果不相等,则将
f[i][j]
设置为false
;如果相等,则将f[i][j]
的值取决于f[i + 1][j - 1]
的值。 - 在内层循环中,如果
f[i][j]
为true
,并且当前子串的长度大于已知的最大回文子串长度mx
,则更新mx
和子串的起始位置begin
。 - 最后,返回子串
s.substring(begin, begin + mx)
作为最长回文子串。
Code
查看代码
java
class Solution {
public String longestPalindrome(String s) {
int n = s.length();
int mx = 1, begin = 0;
boolean[][] f = new boolean[n][n];
for(int i = 0; i < n; i++){
Arrays.fill(f[i], true);
}
char[] g = s.toCharArray();
for(int len = 2; len <= n; len++){
for(int i = 0; i < n; i++){
int j = i + len - 1;
if(j >= n) break;
if(g[i] != g[j]){
f[i][j] = false;
}else{
f[i][j] = f[i + 1][j - 1];
}
if(f[i][j] && len > mx){
mx = len;
begin = i;
}
}
}
return s.substring(begin, begin + mx);
}
}