写代码的第三十八天
好忙啊啊啊啊啊,没时间啦啊啊啊啊
1143.最长公共子序列
思路
解决问题1:dp[i][j]数组的含义是什么?意思是从0到i-1以及从0到j-1的最长公共子序列。
解决问题2:递推公式是什么?分为两种情况,第一种是当前的nums1[i][j]==nums2[i][j]时有相等的元素,所以在dp[i-1][j-1]的基础上+1;第二种是当前nums1[i][j]不等于nums2[i][j]的情况,那么本题要求的最长公共子序列不要求必须连续,所以当前不相等,可以看nums1[i][j]和nums1[i-1][j]的最长公共子序列以及nums1[i][j]和nums1[i][j-1]的最长公共子序列,将两个子序列进行比较,留下最大的那个。
解决问题3:dp数组如何初始化?通过上面的递推公式可以看出,ij由i-1 j-1以及i j-1以及i-1 j三个位置的值决定的,所以要求ij一定要讲前面的值求出来,所以要将dp00,dp10,dp01进行初始化,初始化的数值按照dp数组的含义全部赋值为0,其他位置的dp值赋值为什么都可以,都会被后续计算的数值覆盖掉。
解决问题4:for循环的顺序?按照递推公式可以知道,是从左到右从上到下。
正确代码:
class Solution:
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
dp = [[0 for _ in range(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-1][j],dp[i][j-1])
return dp[len(text1)][len(text2)]
1035.不相交的线
思路
和上一个题完全一致!!!!
class Solution:
def maxUncrossedLines(self, nums1: List[int], nums2: List[int]) -> int:
dp = [[0 for _ in range(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-1][j],dp[i][j-1])
return dp[len(nums1)][len(nums2)]
53. 最大子序和
思路
dp[i]数组指的是连续子数组的最大和。
错误第一版:递推公式思路错了,我的想法是只要这个nums[i]是负数,那么这个值一定不能加上去,也一定不会比dp[i-1]大,所以dp[i] = dp[i-1],但是实际上这种情况的递推公式应该是从nums[i]开始在计算,因为并不是有负数都跳过才会得到最大值!!!而且也不是所有的数组加和都大于单独的一个数,比如说【1,1,1,1,100】.
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
if not nums:
return 0
dp = [0] * (len(nums))
dp[0] = nums[0]
for i in range(1,len(nums)):
if nums[i] < 0:
dp[i] = dp[i-1]
else:
dp[i] = dp[i-1] + nums[i]
return dp[-1]
正确代码:
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
if not nums:
return 0
dp = [0] * (len(nums))
dp[0] = nums[0]
for i in range(1,len(nums)):
dp[i] = max(nums[i], dp[i-1] + nums[i])
return max(dp)
392.判断子序列
思路
这个题和最长公共子序列几乎一致,就是最后加一个判断。
解决问题1:dp[i][j]的含义是什么?下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t,相同子序列的长度为dp[i][j]。
正确代码:
class Solution:
def isSubsequence(self, s: str, t: str) -> bool:
dp = [[0 for _ in range(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] = max(dp[i-1][j],dp[i][j-1])
if dp[-1][-1] == len(s):
return True
else:
return False