题目描述:
给你一个字符串 s,找到 s 中最长的回文子串。 示例 1: 输入:s = “babad” 输出:“bab” 解释:“aba”
同样是符合题意的答案。示例 2: 输入:s = “cbbd” 输出:“bb”
示例 3: 输入:s = “a” 输出:“a”
示例 4: 输入:s = “ac” 输出:“a”
提示: 1 <= s.length <= 1000 s 仅由数字和英文字母(大写和/或小写)组成
做题思路(主要介绍动态规划)
- 暴力法(思路:设置low,high指针,判断low,high之间的元素是不是回文,找出最长)
- 动态规划(本文重点介绍)
动态规划:
- 使用arr[len][len] 二位数组保存状态,arr[i][j] == 1,表示i -> j是回文
- 可知,arr[0][0] , arr[1][1] , arr[2][2]…一定是回文,所以初始化的时候可以设定为1
- 大规模依赖于小规模,arr[i][j]如果是,arr[i+1][j-1]一定是(i+1,j-1合法)
代码如下:C++
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
class Solution {
public:
string longestPalindrome(string s) {
int start = 0;
int maxNum = 1;//最大的长度初始化1
int len = s.length();
//int arr[len][len];//初始化
vector<vector<int>> arr(len, vector<int>(len, 0));
for(int i = 0; i < len; i ++) {
arr[i][i] = 1;//对角线一定是
}
for(int j = 1; j < len; j ++) {
// for(int i = j-1; i>=0; i --) {
for(int i = 0; i < j; i ++) {
if(s[i] != s[j]) arr[i][j] = 0;
else {//两端相等
if(j - i + 1 <= 3) {//长度小于3时候
arr[i][j] = 1;
}
else {
arr[i][j] = arr[i + 1][j - 1];//大规模=小规模
}
if(arr[i][j] && j - i + 1 > maxNum) {
maxNum = j - i + 1;
start = i;
}
}
}
}
return s.substr(start,maxNum);
}
};