代码随想录算法训练营第五十三天| 1143. 最长公共子序列,1035. 不相交的线,53. 最大子数组和
1143. 最长公共子序列
题目链接:最长公共子序列
i/j | c | e | a | |
---|---|---|---|---|
g | ||||
h | ||||
a | 1 | |||
b | 0 | 1 | ||
a | 0 | 1 |
一直想不明白,上面那种情况第二个a怎么样才能不配上,原来是左上方,左上方就是一边是’ce’没有a,一边是’ghab’,那么text1的第二个a就可以和text2的a成为第一次匹配,不用管text1里的第一个a了。
class Solution:
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
# #dp[i][j] = text1[:i]和text2[:j]的两个字符串的最长公共子序列的长度。
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])
return dp[-1][-1]
1035. 不相交的线
题目链接:不相交的线
完全没看出来,本题说是求绘制的最大连线数,其实就是求两个字符串的最长公共子序列的长度!和上一题一样。
class Solution:
def maxUncrossedLines(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
else:
dp[i][j] = max(dp[i][j-1],dp[i-1][j])
return dp[-1][-1]
53. 最大子数组和
题目链接:最大子数组和
贪心算法
第三十一天
动态规划
还挺神奇,所以连续子集的问题,dp的含义还是得考虑一下以nums[i]为结尾的最大连续子序列,比考虑nums[:(i+1)]的最佳结果更好。
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
# dp[i]:包括下标i(以nums[i]为结尾)的最大连续子序列和为dp[i]。
dp = [0]*len(nums)
dp[0] = nums[0]
for i in range(1,len(nums)):
# 要nums[i] dp[i-1]+nums[i]
# 前面连续的子集都不要了,重新开始 nums[i]
dp[i] = max(dp[i-1]+nums[i],nums[i])
#print(dp)
return max(dp)