300.最长递增子序列
力扣链接
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。子序列中的元素不要求在原数组中连续。
思路
- 确定dp含义
dp[i]表示以下标i为结尾的最长递增子序列长度 - 确定递推公式
if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1);
- 初始化
全初始化为1,因为最长子序列至少包括自己 - 确定遍历方向
从前往后
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
if len(nums)<=1:
return len(nums)
dp = [1] * len(nums)
for i in range(1,len(nums)): # 遍历数组 nums 中的每一个元素
for j in range(0, i):
# 对于每一个 i,内层循环会遍历从 0 到 i-1 的所有元素。
# 找到所有以 nums[j] 结尾的递增子序列,并考虑将 nums[i] 加到这些子序列的末尾
if nums[i]>nums[j]:
dp[i] = max(dp[i], dp[j]+1)
return max(dp)
674. 最长连续递增序列
力扣链接
给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。
思路
区别在于连续
- 确定dp含义
dp[i]表示以下标i为结尾的最长连续递增子序列长度 - 确定递推公式
本题要求连续递增子序列,所以就只要比较nums[i]与nums[i - 1],而不用去比较nums[j]与nums[i] (j是在0到i之间遍历)。因此只需要单层循环比较dp[i] 和dp[i-1] 即可。
dp[i] = dp[i - 1] + 1
- 初始化
全初始化为1,因为最长子序列至少包括自己 - 确定遍历方向
从前往后
class Solution:
def findLengthOfLCIS(self, nums: List[int]) -> int:
if len(nums) <= 1:
return len(nums)
dp = [1] * len(nums)
for i in range(1,len(nums)):
if nums[i] > nums[i-1]:
dp[i] = dp[i-1]+1
return max(dp)
718. 最长重复子数组
力扣链接
给两个整数数组 nums1 和 nums2 ,返回 两个数组中 公共的 、长度最长的连续子数组的长度 。
思路
- 确定dp含义
dp[i][j]以下标i-1结尾的数组A和以下标j-1结尾的数组B,他俩的最长重复子数组长度为dp[i][j] - 确定递推公式
当A[i - 1] 和B[j - 1]相等的时候,dp[i][j] = dp[i - 1][j - 1] + 1; - 初始化
全初始化为0 - 确定遍历方向
双层循环,外层for遍历A,内层for遍历B
class Solution:
def findLength(self, nums1: List[int], nums2: List[int]) -> int:
dp = [ [0] * (len(nums2)+1) for _ in range(len(nums1) + 1)]
for i in range(1, len(nums1)+1):
for j in range(1, len(nums2)+1):
if nums1[i-1]==nums2[j-1]:
dp[i][j] = dp[i-1][j-1] + 1
return max(max(row) for row in dp)