持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第23天,点击查看活动详情
最近一直在力扣刷题,也逐渐对各类题型有了自己的理解,所谓见招拆招,将自己的浅显经验分享一下,帮助更多在编程路上的朋友们。
最长回文子串
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入: s = "babad"
输出: "bab"
解释: "aba" 同样是符合题意的答案。
示例 2:
输入: s = "cbbd"
输出: "bb"
提示:
1 <= s.length <= 1000s仅由数字和英文字母组成
思路
使用动态规划并不是最优的解法,时间复杂度还是很高,但比较容易理解。
对于字符串"baab"来说,如果"aa"是回文子串,其两侧的字符相同,则加上两侧的字符后也是回文子串。
定义dp[i][j]为从位置 i 到 位置 j 的子串是否为回文子串。状态转移方程也很容易想到:
dp[i][j] = dp[i + 1][j - 1] && s.charAt(i) == s.charAt(j)。
单个字符即为回文子串,如果两个相邻字符相同,也属于回文子串,我们需要不停的遍历整个字符串,确保能获得最长的回文子串。
在遍历时需要根据长度来遍历,如果根据位置从前往后遍历,会漏掉很多情况,因为dp[i][j]的定义就是根据长度来定义的,长度由小到大才能考虑到每一种情况。
题解
class Solution {
public String longestPalindrome(String s) {
int n = s.length();
char[] c = s.toCharArray();
int start = 0, end = 0;
boolean[][] dp = new boolean[n][n];
for(int i = 0; i < n; i++) {
dp[i][i] = true;
}
for(int len = 2; len <= n; len++) {
for(int left = 0; left + len <= n; left++) {
int right = left + len - 1;
if(len == 2 && c[left] == c[right]) {
dp[left][right] = true;
}else if(dp[left + 1][right - 1] && c[left] == c[right]) {
dp[left][right] = true;
}
if(dp[left][right]) {
start = left;
end = right;
}
}
}
return s.substring(start, end + 1);
}
}