leetcode最长回文字符串_动态规划

1、问题描述

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 长度最长为1000。

示例:

输入: "babad"

输出: "bab"

注意: "aba"也是有效答案

2、问题解析

使用dp[i][j]代表从i到j最长的回文字符串的长度

如果一个字符串的首尾字符相同,并且中间的部分也是回文字符串(dp[i+1][j-1]==j-i+1)那么它也是回文字符串

这时候dp[i][j]=dp[i+1][j-1]+2;

如果不是两个字符不相同或者中间部分不是回文字符串的话,那么就在它的两个子串(dp[i+1][j],dp[i][j-1])中选择较大的那个。

3、问题记录

期间犯了三个错误:

1)没考虑字符串长度为0的情况,并且初始化最大长度biggest应该为1

2)回文字符串的判断有问题:一开始只考虑了首尾两字符相等,没有考虑剩余的子串也需要是回文字符串

3)只有dp[i][j]大于biggest的时候,才能更新biggest和begin的值

4、代码:

class Solution {
public:
	string longestPalindrome(string s) {
		int len = s.length();
		if (len == 0)return "";
		int i, j;
		vector> dp(len, vector(len));//dp[i][j]代表从i到j最长的回文字符串长度
		int biggest=1, begin=0;
		for (i = 0; i < len; ++i) {
			dp[i][i] = 1;
		}
		for (i = len - 2; i >=0; --i) {
			for (j = i + 1; j < len; ++j) {
				if (s[j] == s[i]&&(j-i-1)==dp[i+1][j-1]) {//如果首尾两字符相同并且剩余字符长度是最大回文长度,可以判断是回文字符串
					dp[i][j] = dp[i + 1][j - 1] + 2;
					if(dp[i][j]>biggest){//始终记录最大的长度和起始位置
						biggest= dp[i][j];
						begin = i;
					}
				}
				else {
					dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
				}
			}
		}
		return s.substr(begin, biggest);
	}
};

你可能感兴趣的:(算法与数据结构)