300. 最长递增子序列
1. first idea
dp[i]表示nums[:i]中最长递增子序列的长度。
我们在第i个位置上选择考虑当前元素和不考虑当前元素进最长递增子序列。
如果当前元素破坏了递增的规则,那么一定不能纳入。
dp[i] = dp[i - 1]
如果当前元素符合递增,那么考虑纳入或不纳入。
dp[i] = max(dp[i - 1] + 1, dp[i - 1])
这个想法是不对的。
2. doc reading
递推式应该是找到j从0到i-1的所有位置对应最长子序列长度dp[j]中,能够纳入nums[i]这个数的,然后将其纳入,并求最大长度。
就是dp[i]
即
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
dp = [1] * len(nums)
max_len = 1
for i in range(len(dp)):
for j in range(i):
if nums[i] > nums[j]:
# nums[i]符合条件
dp[i] = max(dp[i], dp[j] + 1)
# dp[i] 现在保存的是包含nums[i]在内数组的最长递增子序列长度
max_len = max(dp[i], max_len)
# print(dp)
return max_len
674. 最长连续递增序列
1. first idea
dp[i]表示包含nums[i]的最长连续递增子序列长度。
遇到不满足递增的nums[i],那么就dp[i]=1.
满足递增nums[i], dp[i] = dp[i - 1] + 1.
最后对整个状态表求最大值即可。
class Solution:
def findLengthOfLCIS(self, nums: List[int]) -> int:
dp = [1] * len(nums)
for idx in range(1, len(nums)):
if nums[idx] > nums[idx - 1]:
dp[idx] = dp[idx - 1] + 1
return max(dp)
718. 最长重复子数组
1. first idea
双层循环。
如果nums1[i]和nums1[j]不相同,说明包含当前nums1[i]的子数组与包含nums2[j]的子数组之间不再匹配,dp[i][j]就为0。
否则,dp[i][j]=dp[i - 1][j - 1] + 1
但是我们一开始该怎么赋初始值呢?
2. doc reading
我们给整个dp矩阵的左侧和上侧多加一行0.
这样就能前推了。
class Solution:
def findLength(self, nums1: List[int], nums2: List[int]) -> int:
dp = [[0] * (len(nums2) + 1) for _ in range(len(nums1) + 1)]
max_len = 0
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
max_len = max(dp[i][j], max_len)
return max_len