加油,坚持!滴水石穿,从此offer到手,从此offer不再是路人。
一、最长递增子序列
leetcode题目链接:300.最长递增子序列
题目描述:
给你一个整数数组
nums
,找到其中最长严格递增子序列的长度。子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。
例如,
[3,6,2,7]
是数组[0,3,1,6,2,2,7]
的子序列。
按照动归五部曲的步骤来处理一下本题:
- 1、dp[i]定义
dp[i] 以nums[i]为结尾的最长子序列长度
- 2、递推公式
dp[i] = max(dp[i]+1, dp[i])
- 3、初始化
dp[i] = 1
- 4、遍历顺序:i从小到大去遍历
- 5、打印dp数组
具体来看一下在leetcode上AC的代码吧:
var lengthOfLIS = function(nums) {
let dp = Array(nums.length).fill(1);
let result = 1;
for (let i = 1;i < nums.length;i++) {
for (let j = 0;j < i;j++) {
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j]+1);
}
}
result = Math.max(result, dp[i]);
}
return result;
};
二、最长连续递增序列
leetcode题目链接:674. 最长连续递增序列
题目描述:
给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。
连续递增的子序列 可以由两个下标
l
和r
(l < r
)确定,如果对于每个l <= i < r
,都有nums[i] < nums[i + 1]
,那么子序列[nums[l], nums[l + 1], ..., nums[r - 1], nums[r]]
就是连续递增子序列。
本题的关键点就是需要跟i-1进行比较,来看一下可以提交通过的代码吧:
const findLengthOfLCIS = (nums) => {
let dp = new Array(nums.length).fill(1);
for(let i = 0; i < nums.length - 1; i++) {
if(nums[i+1] > nums[i]) {
dp[i+1] = dp[i]+ 1;
}
}
return Math.max(...dp);
};
三、最长重复子数组
leetcode题目链接:718. 最长重复子数组
题目描述:
给两个整数数组
nums1
和nums2
,返回 两个数组中 公共的 、长度最长的子数组的长度 。
这一题也是动态规划来解决比较合适,需要用二维数组。
const findLength = (A, B) => {
// A、B数组的长度
const [m, n] = [A.length, B.length];
// dp数组初始化,都初始化为0
const dp = new Array(m + 1).fill(0).map(x => new Array(n + 1).fill(0));
// 初始化最大长度为0
let res = 0;
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
// 遇到A[i - 1] === B[j - 1],则更新dp数组
if (A[i - 1] === B[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
}
// 更新res
res = dp[i][j] > res ? dp[i][j] : res;
}
}
// 遍历完成,返回res
return res;
};