重练算法(代码随想录版) day43 - 动态规划part10
今日刷题量:3
当前刷题总量:159
Easy: 61
Mid: 89
Hard: 9
Day43
解题思想
300 最长递增子序列 LIS(不要求连续)
- 关键点
- 子序列:可以跳元素,只要保持相对顺序
- 目标:最长“严格递增”长度
*** 两种解法**
1.DP O(n²)
- dp[i]:以 nums[i] 结尾的 LIS 长度
- 转移:看所有 j<i 且 nums[j] < nums[i]:dp[i]=max(dp[i], dp[j]+1)
2.贪心 + 二分 O(n log n)
- tails[len-1]:长度为 len 的递增子序列的最小结尾
- 每个数用 lower_bound 找第一个 >=x 替换,或追加到末尾
- tails 长度就是答案
- 同样长度下“结尾越小越容易延长”
674 最长连续递增子序列 LCIS(必须连续)
- 关键点
- 子数组/连续段:不能跳
- 目标:最长连续严格递增段长度
- 思想
- 用“当前连续递增长度”滚动即可:
- 若 nums[i] > nums[i-1]:cur++
- 否则:cur=1
- 同时维护 ans=max(ans,cur)
- 本质是一次线性扫描找最长上升“run”
718 最长重复子数组(两个数组、必须连续且相同)
- 关键点
- 两个数组中找一段连续且完全相同的片段
- 等价于“最长公共子串(substring)”的数组版
- DP 思想
- dp[i][j]:以 A[i-1] 和 B[j-1] 结尾的最长公共连续长度
- 转移:
- 若相等:dp[i][j]=dp[i-1][j-1]+1
- 否则:dp[i][j]=0(连续断了就清零)
- 答案是所有 dp[i][j] 的最大值
- 可优化到一维:dp[j] 表示当前 i 行的 dp[i][j],j 必须倒序
总结:
- 300:不连续、单数组、递增 → “结尾 dp / tails 最小结尾”
- 674:连续、单数组、递增 → “线性扫描数连续上升段”
- 718:连续、双数组、相等 → “最长公共子串 dp(相等+1,不等清零)”
练习题目
300.最长递增子序列(mid):https://leetcode.cn/problems/longest-increasing-subsequence/
674. 最长连续递增序列(easy):https://leetcode.cn/problems/longest-continuous-increasing-subsequence/description/
718. 最长重复子数组(mid):https://leetcode.cn/problems/maximum-length-of-repeated-subarray/description/

浙公网安备 33010602011771号