一、最长公共子序列
这里的子序列和上一题的子数组不同点在于,这里的子序列不要求连续,只要求相对顺序
五部曲
- 确定dp数组以及含义,
dp[i][j],表示0到i-1,的字符串text1和0到j-1的字符串text2之间的最长公共子序列 - 递推公式
- 如果
text1[i-1] === text2[j-1],则dp[i-1][j-1] + 1 - 如果
text1[i-1] !== text2[j-1],则Math.max(dp[i-1][j], dp[i][j-1])
- 如果
- 初始化,统一初始化为0
- 遍历顺序,从前到后
- 举例推导
时间复杂度: O(n * m),其中 n 和 m 分别为 text1 和 text2 的长度 空间复杂度: O(n * m)
/**
* @param {string} text1
* @param {string} text2
* @return {number}
*/
var longestCommonSubsequence = function(text1, text2) {
let dp = new Array(text1.length + 1).fill(0).map(_ => new Array(text2.length + 1).fill(0))
for(let i = 1; i <= text1.length;i++) {
for(let j = 1; j <= text2.length; j++) {
if(text1[i-1] === text2[j-1]) {
dp[i][j] = dp[i-1][j-1] + 1
} else {
dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1])
}
}
}
return dp[text1.length][text2.length]
};
二、不相交的线
本题最大连线数,其实就是求两个字符串的最长公共子序列的长度,和上题完全一样
三、最大子序和
找到最大和的连续子数组
五部曲
- dp数组的含义,
dp[i],i结尾的最大连续子数组和 - 确定递推公式,
Math.max(nums[i] + dp[i-1], nums[i]),其实就是这两种情况的最大值 - 确定遍历顺序,从前往后
- 初始值,
dp[0] = nums[0] - 举例推导
最终返回的是dp中最大的值,而不是最后一个值
var maxSubArray = function (nums) {
let dp = []
dp[0] = nums[0]
let result = nums[0]
for (let i = 1; i < nums.length; i++) {
dp[i] = Math.max(dp[i - 1] + nums[i], nums[i])
result = Math.max(result, dp[i])
}
return result
};