300.最长递增子序列
题目链接:https://leetcode.cn/problems/longest-increasing-subsequence/
文档讲解:https://programmercarl.com/0300.%E6%9C%80%E9%95%BF%E4%B8%8A%E5%8D%87%E5%AD%90%E5%BA%8F…
视频讲解:https://www.bilibili.com/video/BV1ng411J7xP
思路
- 确定dp数组以及下标的含义:以
nums[i]
为结尾的最长递增子序列的长度为dp[i]
。 - 确定递推公式:如果
nums[i] > nums[j]
,那么dp[i] = dp[j] + 1
。递推公式为dp[i] = Math.max(dp[i], dp[j] + 1)
。 - dp数组如何初始化:都初始化为1。
- 确定遍历顺序:正序。
- 打印dp数组,用于debug
代码
class Solution {
public int lengthOfLIS(int[] nums) {
int[] dp = new int[nums.length];
Arrays.fill(dp, 1);
for (int i = 1; i < nums.length; i++) {
for (int j = 0; j < i; j++) {
if (nums[j] < nums[i]) dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
int res = 0;
for (int i = 0; i < dp.length; i++) {
res = Math.max(res, dp[i]);
}
return res;
}
}
分析:时间复杂度:O(n2),空间复杂度:O(n)。
674. 最长连续递增序列
题目链接:https://leetcode.cn/problems/longest-continuous-increasing-subsequence/
文档讲解:https://programmercarl.com/0674.%E6%9C%80%E9%95%BF%E8%BF%9E%E7%BB%AD%E9%80%92%E5%A2%9E…
视频讲解:https://www.bilibili.com/video/BV1bD4y1778v
思路
- 确定dp数组以及下标的含义:以
nums[i]
为结尾的最长连续递增子序列的长度为dp[i]
。 - 确定递推公式:只有当
nums[i] > nums[i - 1]
时,dp[i] = Math.max(dp[i], dp[i - 1] + 1);
;否则将dp[i]
的值置为1。 - dp数组如何初始化:都初始化为1。
- 确定遍历顺序:正序。
- 打印dp数组,用于debug
代码
class Solution {
public int findLengthOfLCIS(int[] nums) {
int[] dp = new int[nums.length];
Arrays.fill(dp, 1);
int res = 1;
for (int i = 1; i < nums.length; i++) {
for (int j = 0; j < i; j++) {
if (nums[i] > nums[i - 1]) dp[i] = Math.max(dp[i], dp[i - 1] + 1);
else dp[i] = 1;
}
res = Math.max(res, dp[i]);
}
return res;
}
}
分析:时间复杂度:O(n2),空间复杂度:O(n)。
718. 最长重复子数组
题目链接:https://leetcode.cn/problems/maximum-length-of-repeated-subarray/
文档讲解:https://programmercarl.com/0718.%E6%9C%80%E9%95%BF%E9%87%8D%E5%A4%8D%E5%AD%90%E6%95%B0…
视频讲解:https://www.bilibili.com/video/BV178411H7hV
思路
- 确定dp数组以及下标的含义:以
i - 1
为结尾的nums1
子数组与以j - 1
为结尾的nums2
子数组的最长重复子数组长度为dp[i][j]
。 - 确定递推公式:
if (nums1[i] == nums2[j]) dp[i][j] = dp[i - 1][j - 1] + 1;
- dp数组如何初始化:第一行和第一列初始化为0,没有意义。
- 确定遍历顺序:正序。
- 打印dp数组,用于debug
代码
class Solution {
public int findLength(int[] nums1, int[] nums2) {
int[][] dp = new int[nums1.length + 1][nums2.length + 1];
int res = 0;
for (int i = 1; i <= nums1.length; i++) {
for (int j = 1; j <= nums2.length; j++) {
if (nums1[i - 1] == nums2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;
res = Math.max(res, dp[i][j]);
}
}
return res;
}
}
分析:时间复杂度:O(mn),空间复杂度:O(mn)。分别为两个数组的长度。
复习
链表理论基础
203.移除链表元素
707.设计链表
206.反转链表
24. 两两交换链表中的节点
19.删除链表的倒数第N个节点
面试题 02.07. 链表相交 (同:160.链表相交)
142.环形链表II
链表部分总结