300.最长递增子序列
题目描述: 300.最长递增子序列.
解法
dp
python
class Solution(object):
def lengthOfLIS(self, nums):
if len(nums) <= 1:
return len(nums)
dp = [1] * len(nums)
res = 0
for i in range(1,len(nums)):
for j in range(i):
if nums[j] < nums[i]:
dp[i] = max(dp[i],dp[j]+1)
res = max(res,dp[i])
return res
考虑的是:以当前节点为终点的递增序列,最长为多少。
674. 最长连续递增序列
题目描述: 674. 最长连续递增序列.
解法
dp
python
class Solution(object):
def findLengthOfLCIS(self, nums):
if len(nums) <= 1:
return len(nums)
dp = [1] * len(nums)
res = 0
for i in range(1,len(nums)):
if nums[i-1] < nums[i]:
dp[i] = dp[i-1] + 1
res = max(res,dp[i])
return res
718. 最长重复子数组
题目描述: 718. 最长重复子数组.
解法
二维dp
python
class Solution:
def findLength(self, nums1: List[int], nums2: List[int]) -> int:
dp = [[0] * (len(nums1)+1) for _ in range(len(nums2)+1)]
res = 0
for i in range(1,len(nums2)+1):
for j in range(1,len(nums1)+1):
if nums2[i-1] == nums1[j-1]:
dp[i][j] = dp[i-1][j-1] + 1
res = max(res,dp[i][j])
return res
滚动dp
python
class Solution(object):
def findLength(self, nums1, nums2):
dp = [0]*(len(nums1)+1)
res = 0
for i in range(1,len(nums2)+1):
for j in range(len(nums1),0,-1):
if nums2[i-1] == nums1[j-1]:
dp[j] = dp[j-1] + 1
else:
dp[j] = 0
res = max(res,dp[j])
return res
只要dp[i][j]是由dp[i-1][j]或者dp[i-1][j-1]决定的,就可以使用滚动数组
本体的主要思路就是,遍历每个字符串的每一位,然后对比以该位为终点的相同的子串有多少位,如果该位相同,那就在前一位的基础上+1,否则的话,就置为0
1143.最长公共子序列
题目描述: 1143.最长公共子序列.
解法
二维dp
python
class Solution(object):
def longestCommonSubsequence(self, text1, text2):
dp = [[0] * (len(text2)+1) for _ in range(len(text1)+1)]
for i in range(1,len(text1)+1):
for j in range(1,len(text2)+1):
if text1[i-1] == text2[j-1]:
dp[i][j] = dp[i-1][j-1] + 1
else:
dp[i][j] = max(dp[i][j-1],dp[i-1][j])
res = max(res,dp[i][j])
return dp[len(text1)][len(text2)]
需要考虑两个字符串任意减少一个的情况
子序列和子数组不同的就在于,子数组一定是连续的,所以考虑dp[i][j]时一定要考虑dp[i-1][j-1]
但是子序列就不一样了,如果dp[i][j]不能由dp[i-1][j-1]得到,那就得考虑每个单词各削减一位的情况了。
同样,因为是子序列,所以不需要考虑最长在哪,返回最后的dp就一定是最长的子序列长度
滚动dp
python
class Solution(object):
def longestCommonSubsequence(self, text1, text2):
dp = [0]* (len(text1)+1)
res = 0
for i in range(1,len(text2)+1):
pre = 0
for j in range(1,len(text1)+1):
cur = dp[j]
if text1[j-1] == text2[i-1]:
dp[j] = pre + 1
else:
dp[j] = max(dp[j],dp[j-1])
pre = cur
return dp[len(text1)]
当使用滚动dp时,就要考虑当前的这个元素和什么有关,如果仅是和上有关,那就可以将dp的内容倒序更新,但是如果和左也有关系,那就只能正序更新,然后记录更新之前的当前元素。