前言
今天是我们开始更文的第一天,只许成功,不许失败,所以挑了一个已经有解题思路的动态规划题目:
在此就不对题目进行详细描述了,直接开始我的表演吧:
找规律
-
1、对于回文字符串
ababa来说,除去首尾字符以后(bab)也同样是回文字符串; -
2、如果字符串长度为1,那必定是回文,不做赘述;
-
3、所以我们对于指定长度
n的字符串来说,第一步就是要看他首尾字符是否相等,假设该段字符串在总字符串中的起始索引为i,终止索引为j,其中因为长度为n,所以j = n - i - 1;判断标准为s[i] == s[j]; -
4、接着上一步,如果首尾字符串相等了,那我们就需要看除去首尾字符的中间子串是否为回文,也就是起始索引 + 1,终止索引 - 1,往中间靠,如果不相等,那这段字符串就排除;
-
5、重复上面两步过程,直到中间只剩1个字符或者2个字符,为啥呢?因为只剩两个字符我们就可以直接判断出是否符合回文的要求。
上代码
var longestPalindrome = function(s) {
// 记录字符串总长度
const len = s.length;
// 记录当前最长回文子串
let res = "";
// 二维数组来表示一段字符是否为回文,是则true,否则false
// 如[i][j]表示从i索引到j索引的字符串是否为回文
const dp = new Array(len);
for (let i = 0; i < len; i++) {
dp[i] = [];
}
// 这里l千万别看成数字1哦
for (let l = 1; l <= len; l++) {
// 长度为l,起始索引最多可以到达 len - l
for (let i = 0; i <= len - l; i++) {
// 通过起始索引i和字符长度l得到终止索引j
let j = i + l - 1;
if (l == 1) {
// 只有一个字符,那肯定是回文
dp[i][j] = true;
} else if (l == 2) {
// 两个字符的时候,比较首尾是否相等即可
dp[i][j] = s[i] == s[j];
} else {
// 就是规律中所说的3、4步
dp[i][j] = s[i] == s[j] && dp[i+1][j-1];
}
// 从索引i到索引j的字符串为回文,且这段长度比当前最长回文子串长,则更新这段字符串为最长
if (dp[i][j] && j - i + 1 > res.length) {
res = s.slice(i, j+1);
}
}
}
return res;
};
自我鼓励
- 不坚持怎么会坚挺
- 光羡慕是没有用的,我们要行动起来