打造保姆级题解,一次只写一种解法降低学习成本。
Leetcode 5.最长回文子串
解题思路
找到最长的回文字串,可以采用枚举的方式找到全部的回文字串,再从中得到最长的那个。
babad,这个字符串中,如果 dp[2][2] 是回文字串,那么。dp[1][3] 也是回文字串,也就是说,子问题的结果可以推导出更大问题的结果。这里存在最优子结构,所以我们采用动态规划的方式来求解。
- 定义状态
dp[i][j] 表示当前的结果是否是最优子结构,因为要一个开头,一个结尾,所有需要一个二维数组。
- 得出状态转移返程
当前项是否是
对数组进行遍历,满足以下两种情况时dp[i][j]的结果是 true,否则是false 开始位置和结束位置指向的数相等,且当前的两个数相邻或是同一个数。 开始位置和结束位置指向的数相等,且满足子结构的结果是true
dp[i][j] = s[i] == s[j] && (j - i < 2 || dp[i+1][j-1]);
-
初始化状态,都是
false -
返回结果
代码
var longestPalindrome = function(s) {
let n = s.length;
let res = '';
let dp = Array.from(new Array(n),() => new Array(n).fill(false));//初始化数组
for(let i = n-1;i >= 0;i--){// 从后往前遍历
for(let j = i;j < n;j++){ // 从前往后遍历
dp[i][j] = s[i] == s[j] && (j - i < 2 || dp[i+1][j-1]);
if(dp[i][j] && j - i +1 > res.length){
res = s.substring(i,j+1); // 当前回文子串比之前的大,更新最大长度
}
}
}
return res;
};
详细解释
1. 最优子结构
最优子结构是说可以从子问题的最优结果,推出更大规模问题的最优结果。
比如要从全校选出同学去参加全区的跑步比赛,全校有10个班级的同学,计算每个班跑最快的同学是子问题,在知道所有子问题的答案后就可以在这10个b班级的最高分中得到全校最高分。
2. 重叠子问题
在做斐波那契算法的时候,fib(3)的两次结果是重复的,这就是重叠子问题。
2. 回文字符串
“回文串”是一个正读和反读都一样的字符串,初始化标志flag=true,比如“level”或者“noon”等等就是回文串。
3. subString
str.substring(start, end)方法同样是截取字符串,两个参数分别表示开始和结束的位数,类似slice,但是不同的是substring不接受负数,并且如果start值大于end的值,则会自动交换两个位置
let str = "123456"
str.substring.subString(0, 1) // 1
str.substring.subString(5) // 6
4. Array.from
Array.from()方法从类似数组或可迭代对象创建一个新的(浅拷贝)的数组实例..
Array.from(arrayLike,mapFn,thisArg)
- arrayLike:必选,想要转换成数组的伪数组对象或可迭代对象
- mapFn:可选,如果指定了该参数,新数组中的每个元素会执行该函数
- thisArg:可选,执行回调函数mapFn时this对象