重练算法(代码随想录版) 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/

posted @ 2025-12-17 16:13  GengarF  阅读(3)  评论(0)    收藏  举报