From ed62e1dd7100a1e0ccba5c1f86813b376608f845 Mon Sep 17 00:00:00 2001 From: Sainnhe Park Date: Fri, 10 Feb 2023 12:08:26 +0800 Subject: [PATCH] Add subsequence --- notes/src/SUMMARY.md | 1 + notes/src/subsequence.md | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 notes/src/subsequence.md diff --git a/notes/src/SUMMARY.md b/notes/src/SUMMARY.md index 62de650..abfc0f3 100644 --- a/notes/src/SUMMARY.md +++ b/notes/src/SUMMARY.md @@ -58,6 +58,7 @@ - [背包问题](./knapsack.md) - [打家劫舍](./house-robber.md) - [股票问题](./stock.md) +- [子序列问题](./subsequence.md) # STL diff --git a/notes/src/subsequence.md b/notes/src/subsequence.md new file mode 100644 index 0000000..0f315e4 --- /dev/null +++ b/notes/src/subsequence.md @@ -0,0 +1,38 @@ +# 子序列问题 + +## [300. 最长递增子序列](https://leetcode.cn/problems/longest-increasing-subsequence/) + +- `dp[i]` 表示以 `nums[i]` 结尾的最长递增子序列的长度 +- 遍历 `j` 从 `0` 到 `i`, `if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1)` +- `dp[i] = 1` +- 外层遍历 `i` 内层遍历 `j`,都是从前往后 + +## [674. 最长连续递增序列](https://leetcode.cn/problems/longest-continuous-increasing-subsequence/) + +- `dp[i]` 表示以 `nums[i]` 结尾的最长连续递增子序列的长度 +- 递推公式: + - `if (nums[i] > nums[i - 1]) dp[i] = dp[i - 1] + 1` + - `if (nums[i] <= nums[i - 1]) dp[i] = 1` +- `dp[0] = 1` +- 从前往后 + +## [718. 最长重复子数组](https://leetcode.cn/problems/maximum-length-of-repeated-subarray/) + +- `dp[i][j]` 表示以 `i` 为下标结尾的 A 和以 `j` 为下标结尾的 B 的最长重复子数组 +- `if (nums1[i] == nums2[j]) dp[i][j] = dp[i - 1][j - 1] + 1` 否则为 `0` +- 初始化: + - `if (nums1[i] == nums2[0]) dp[i][0] = 1` 否则为 `0` + - `if (nums1[0] == nums2[j]) dp[0][j] = 1` 否则为 `0` + - 其它都初始化为 `0` +- 都从前往后遍历,下标从 `1` 开始 + +## [1143. 最长公共子序列](https://leetcode.cn/problems/longest-common-subsequence/) + +- `dp[i][j]` 表示以 `i` 为下标结尾的 text1 和以 `j` 为下标结尾的 text2 的最长公共子序列 +- 递推公式 + - `if (text1[i] == text2[j]) dp[i][j] = dp[i - 1][j - 1] + 1` + - `else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])` +- 只需要初始化三个: + - `dp[0][0]` + - `dp[1][0]` + - `dp[0][1]`