515 字
3 分钟
代码随想录算法训练营第三十七天 | 动态规划 Part10

300. 最长递增子序列#

LeetCode 300. Longest Increasing Subsequence

思路:

  • 定义 dp[i] 表示以下标 i 结尾的最长递增子序列的长度;
  • 遍历 ji 之前的元素,如果 nums[i] > nums[j],说明可以接在后面;
  • 状态转移方程:dp[i] = max(dp[i], dp[j] + 1)
  • 最终答案是 max(dp) 中的最大值。
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
dp = [1] * len(nums) # 每个元素都至少可以单独成为子序列
for i in range(len(nums)):
for j in range(i):
if nums[i] > nums[j]:
# 如果当前元素大于前一个元素,则可以接在其后面
dp[i] = max(dp[i], dp[j] + 1)
return max(dp) # 返回最长子序列长度

674. 最长连续递增序列#

LeetCode 674. Longest Continuous Increasing Subsequence

思路:

  • 定义 dp[i] 表示以第 i 个元素结尾的最长连续递增子序列的长度;
  • nums[i] > nums[i - 1],说明可以延续前面的连续递增序列;
  • 否则,重新开始计数;
  • 最终返回 max(dp)
class Solution:
def findLengthOfLCIS(self, nums: List[int]) -> int:
n = len(nums)
dp = [1] * n # 每个元素至少是长度为1的连续递增序列
for i in range(n):
if i > 0 and nums[i] > nums[i - 1]:
# 当前数比前一个数大,延续递增序列
dp[i] = max(dp[i - 1] + 1, dp[i])
return max(dp) # 返回最大长度

718. 最长重复子数组#

LeetCode 718. Maximum Length of Repeated Subarray

思路:

  • 本题类似于“最长公共子串”;
  • 定义 dp[i][j] 表示以 nums1[i-1]nums2[j-1] 结尾的最长相同子数组长度;
  • nums1[i - 1] == nums2[j - 1],则 dp[i][j] = dp[i-1][j-1] + 1
  • 否则 dp[i][j] = 0
  • 答案是所有 dp[i][j] 中的最大值。
class Solution:
def findLength(self, nums1: List[int], nums2: List[int]) -> int:
m, n = len(nums1), len(nums2)
# 多加一行一列,方便处理边界情况
dp = [[0] * (n + 1) for _ in range(m + 1)]
res = 0 # 记录最大长度
for i in range(1, m + 1):
for j in range(1, n + 1):
if nums1[i - 1] == nums2[j - 1]:
# 若元素相等,则在之前的基础上+1
dp[i][j] = dp[i - 1][j - 1] + 1
res = max(res, dp[i][j]) # 更新最大值
return res
代码随想录算法训练营第三十七天 | 动态规划 Part10
https://fuwari.vercel.app/posts/code_musings_day_thirty-seven/
作者
Jarrett
发布于
2025-07-23
许可协议
CC BY-NC-SA 4.0