(先叠个甲,我是初学者)
由这个题可以看出,初步的动态规划就是递归加记忆化。
如何判断回文:
在做这个题之前,已经接触过回文题目,当时的做法是双指针(感觉挺高大上的),是用两个变量记作位置,从两端开始判断是否相等
这个思路似乎没法列出动态规划的状态转移的那个方程(我没想出来),官方题解给出的思路(咱是初学者看题解不丢人,只要能自己再从0到1敲出来,就没关系)大致思路也是这样,但是处理的方法比较巧妙吧(算是),就是像剥洋葱一样,逐层判断。
状态转移方程:P(i,j)=P(i+1,j−1)∧(Si==Sj)
#include <iostream>
#include <string>
#include <vector>
class Solution {
public:
string longestPalindrome(string s) {
int len = s.length();
if (len == 1) {
return s;
}
vector<vector<int>> dp(len, vector<int>(len));
for (int i = 0; i < len; i++)
dp[i][i] = 1; // 长度为1的是回文串
int z = 0, y = 1;
for (int l = 2; l <= len; l++) { // 字串的长度
for (int i = 0; i < len; i++) {
int j =
l + i -
1; // 减少时间复杂度,经典的是鸡兔同笼,通过数学计算减少循环层数
if (j >= len)
break;
if (s[i] != s[j])
dp[i][j] = 0; // 状态转移方程
else {
if (j - i <= 2) // 长度为2的两两相等为回文串,为3确保两头相等
dp[i][j] = 1;
else
dp[i][j] = dp[i + 1][j - 1]; // dp的赋值从小到大进行
}
if (dp[i][j] == 1 && l > y) { // 遇到长度更长会迭代
y = l;
z = i;
}
}
}
return s.substr(z, y);
}
};