300.最长递增子序列
题目链接
思路
1. dp 数组及下标含义
dp[i]:以 nums[i] 结尾的最长严格递增子序列长度
2. 递推公式
遍历 j∈[0,i−1]:若 nums[i]>nums[j](严格递增)dp[i]=max(dp[i], dp[j]+1)
3. 数组初始化
每个元素自身单独构成子序列dp[i]=1
4. 遍历顺序
-
外层:i 从 1 到末尾
-
内层:j 从 0 到 i−1
5. 结果
整个 dp 数组的最大值
提交
python
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
n = len(nums)
# dp[i]:以nums[i]结尾的最长严格递增子序列长度
dp = [1] * n
# 遍历每个位置i
for i in range(n):
# 遍历i前面所有元素j
for j in range(i):
# 满足严格递增,可拼接
if nums[i] > nums[j]:
dp[i] = max(dp[i], dp[j] + 1)
# 全局最大值即为答案
return max(dp)
674. 最长连续递增序列
题目链接 674. 最长连续递增序列 - 力扣(LeetCode)
思路
1. dp 数组含义
dp[i]:以 nums[i] 结尾的最长连续严格递增子数组长度
2. 递推公式
如果满足连续严格递增:nums[i]>nums[i−1],dp[i]=dp[i−1]+1
否则:dp[i]=1
3. 初始化
每个元素自身长度为 1:dp[i]=1
4. 遍历顺序
从左到右,i 从 1 向后遍历
5. 最终结果
取 dp 数组最大值
关键区分
最长递增子序列 LIS:不连续,两层循环 O(n2)
最长连续递增子序列:必须连续,一层循环 O(n)
提交
python
class Solution:
def findLengthOfLCIS(self, nums: List[int]) -> int:
n = len(nums)
# dp[i]:以nums[i]结尾的最长连续递增子数组长度
dp = [1] * n
for i in range(1, n):
# 连续严格递增
if nums[i] > nums[i - 1]:
dp[i] = dp[i - 1] + 1
# 不满足则保持dp[i]=1,单独重新开始
return max(dp)
718. 最长重复子数组
题目链接
思路
1. dp 数组含义
dp[i][j]:表示 nums1 前 i 个元素 和 nums2 前 j 个元素 中,最长公共连续子数组的长度。
2. 递推公式
-
如果
nums1[i-1] == nums2[j-1]:说明当前两个数字相同,可以接在上一段后面 -
dp[i][j] = dp[i-1][j-1] + 1 -
如果不相等:连续中断,
dp[i][j] = 0
3. 初始化
dp[0][j] = 0
dp[i][0] = 0(空数组没有公共子数组)
4. 遍历顺序
两层循环:
-
外层:遍历 nums1
-
内层:遍历 nums2
5. 结果
遍历过程中记录 dp 数组的最大值。
提交
python
class Solution:
def findLength(self, nums1: List[int], nums2: List[int]) -> int:
m = len(nums1)
n = len(nums2)
# dp[i][j]:nums1前i个,nums2前j个,最长公共连续子数组长度
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):
# 当前数字相等,连续长度+1
if nums1[i-1] == nums2[j-1]:
dp[i][j] = dp[i-1][j-1] + 1
# 更新最大值
res = max(res, dp[i][j])
# 不相等时 dp[i][j] 默认为 0,不用处理
return res