5. 最长回文子串

题目

给你一个字符串 s,找到 s 中最长的回文子串。

示例

示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。

示例 2:
输入:s = “cbbd”
输出:“bb”

示例 3:
输入:s = “a”
输出:“a”

示例 4:
输入:s = “ac”
输出:“a”

思路

这道题适用动态规划解决是一个很好的办法。

  1. 先确定dp数组,以及下表的含义
    布尔类型的dp[i][j]:表示区间[i, j]的子串是否为回文字串,如果是那么dp[i][j]为true,否则为false。
  2. 确定递推公式
    我们需要分析集中情况
    当s[i]与s[j]不相同时,那么dp[i][j]为false
    当s[i]与s[j]相同时就需要分情况说明了
  • 下标i与j相同,就是说是一个字符串
  • 下表i与j相差为1,例如aa,也是回文字串
  • 下表i和j相差大于1,例如abcba,此时s[i]和s[j]相同了,这时候就要看i到j区间里的子串是不是回文子串了,也就是说看bcb是不是回文子串了,对应的下表就是i + 1j - 1了。如果是的那么就是true。
  • 得到[i, j]是否是回文子串后,就要保存左边界和右边界和长度。
  1. dp数组的初始化:把数组初始化为0也就是false
  2. 确定遍历顺序
    从上述的递推公式可以看出,第三种情况是要先判断dp[i + 1][j - 1]是否是true再去判断dp[i][j]的。也就是说在表格中dp[i + 1][j - 1]是在dp[i][j]的左下角。
    如果像往常一样从上到下,从左到右遍历数组就会出现一些问题,因为dp[i + 1][j - 1]是在dp[i][j]的后面。所以稍改一下遍历顺序,就是从下到上,从左到右这样就可以保证dp[i][j]需要的dp[i + 1][j - 1]都已经确定好了。
  3. 举例推到dp数组
    “aaa”
    dp[i][j]: [1, 1, 1]
    [0, 1, 1]
    [0, 0, 1]
    左下半部分为0是因为在定义中j是始终大于等于i的。

代码

class Solution {
public:
	string longestPalindrome(string s) {
		vector<vector<int>> dp(s.size(), vector<int>(s.size(), 0));
		int left = 0, max_len = 0;
		for (int i = s.size() - 1; i >= 0; i--) {
			for (int j = i; j < s.size(); j++) {
				if (s[i] == s[j] && (j - i + 1 <= 1 || dp[i + 1][j - 1])) {
					dp[i][j] = true;
				}
				if (dp[i][j] && j - i + 1 > max_len) {
					max_len = j - i + 1;
					left = i;
				}
			}
		}
		return s.substr(left, max_len);
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值