代码随想录算法训练营第四十四天 |动态规划part11
1143 最长公共子序列
思路:和上一题最长重复子数组几乎一样,区别就在于是否连续,上一题要求连续,这一题不要求连续,所以说就需要进行一个else的判断,dp[i] [j] 的值应该是dp[i-1] [j] 和 dp[i] [j-1]的最大值,需要前一次的结果。
# text1 = "abcde"
# text2 = "ace"
dp = [[0] * (len(text2) + 1) for _ in range(len(text1) + 1)]
# dp[i][j] 表示以i-1为结尾的text1 和 以j-1为结尾的text2 的最长公共子序列长度
result = 0
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-1][j], dp[i][j-1])
result = max(result, dp[i][j])
return result
1035 不相交的线
思路:和上一题一模一样,就是求最长公共子序列
dp = [[0] * (len(nums2)+1) for _ in range(len(nums1)+1)]
result = 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
else :
dp[i][j] = max(dp[i-1][j],dp[i][j-1])
if result < dp[i][j]:
result = dp[i][j]
return result
53 最大子数组和
思路:dp[i] [j]保存对应的和。代码如下:会超时,因为有2层for循环
# nums = [5,4,-1,7,8]
# dp[i][j] 以i为开头 j为结尾的子数组的最大和
if len(nums) == 1:
return nums[0]
dp = [[float('-inf') for _ in range(len(nums))] for _ in range(len(nums))]
result = float('-inf')
for i in range(len(nums)):
sum_ = 0
for j in range(i,len(nums)):
sum_ += nums[j]
dp[i][j] = max(dp[i][j-1],sum_)
if result < dp[i][j]: result = dp[i][j]
return (result)
dp[i] = max(dp[i-1]+nums[i-1],nums[i-1])
指的是,前i个数的最大子数组和,是由前i-1个数的最大子数组和 + 第i个数(nums[i-1]) 和 第i个数进行比较的出来的。
可能前i-1个数和为负数,也可能为正数,所以都需要考虑。
本人代码:
# nums = [-2,1,-3,4,-1,2,1,-5,4]
# dp[i] 表示前i个数组的最大子数组和
dp = [0] * (len(nums)+1)
# dp[0] = float('-inf')
result = nums[0]
for i in range(1,len(nums)+1):
dp[i] = max(dp[i-1]+nums[i-1],nums[i-1])
result = max(result,dp[i])
# print(result)
return result
392 判断子序列
思路:感觉和最长公共子序列差不多,只需要返回的长度等于短的字符串的长度即可。
dp = [[0]*(len(t)+1) for i in range(len(s)+1)]
result = 0
for i in range(len(s)):
for j in range(len(t)):
if s[i] == t[j]:
dp[i][j] = dp[i-1][j-1] + 1
else :
dp[i][j] = max(dp[i-1][j],dp[i][j-1])
if result < dp[i][j]:
result = dp[i][j]
return result == len(s)
参考代码:
dp = [[0] * (len(t)+1) for _ in range(len(s)+1)]
for i in range(1, len(s)+1):
for j in range(1, len(t)+1):
if s[i-1] == t[j-1]:
dp[i][j] = dp[i-1][j-1] + 1
else:
dp[i][j] = dp[i][j-1]
if dp[-1][-1] == len(s):
return True
return False