1.1143.最长公共子序列
题目链接:1143.最长公共子序列
文档讲解: 代码随想录
与上一题区别在于,子序列的元素在原序列中不一定连续。
(1)确定数组和下标
dp[i][j]表示A字符串以 i-1 结尾,B字符串以 j-1 结尾的最长子序列的长度
(2)递推关系式
我想叉了,A字符串为‘abcde’,B字符串为’ace’,在比较到 c 相等时,dp[i][j] = dp[i-1][j-1] + 1,因为dp[i-1][j-1]的值并不是指最长子序列必须以[i-1]和[j-1]这两个字母结尾,就是说,c相等,只需要在’ab’和’a’的最长子序列的长度上加一就行,并不需要去纠结 c 前面两个字符串哪个字符相等。
如果A[i-1]=B[j-1],那么dp[i][j] = dp[i-1][j-1] + 1
如果不相等,dp[i][j] = max(dp[i][j-1],dp[i-1][j])
(3)初始化:为0
(4)遍历顺序:两层for循环,都是从前往后
(5)打印
class Solution(object):
def longestCommonSubsequence(self, text1, text2):
"""
:type text1: str
:type text2: str
:rtype: int
"""
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]
2.1035.不相交的线
题目链接:1035.不相交的线
文档讲解: 代码随想录
最大的问题就是如何保证线不相交。举个例子,[1,2]和[2,1],不相交的线只有一条,等同于求最长公共子序列。想到这个的话,这道题和上一题是一模一样的。
class Solution(object):
def maxUncrossedLines(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: 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]
3.53. 最大子序和
这道题之前用贪心做过,这里用动态规划做。
(1)确定数组和下标
dp[i]表示包含元素 i 在内的最大和
(2)递推关系式
dp[i] = max(dp[i-1],dp[i-1]+nums[i]),这个不对,没有考虑到连续,同时最大子序列的和不一定是从nums[0]开始的。
正确:得到dp[i]有两种方法,一种有dp[i-1]延续加上nums[i],还有一种就是从nums[i]从新开始计算。因此dp[i]=max(dp[i-1]+nums[i],nums[i])
(3)初始化
dp[0]=nums[0],其余值为float(‘-inf’)
(4)遍历顺序
从前往后
(5)打印数组
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
dp = [float('-inf')] * len(nums)
dp[0] = nums[0]
res = dp[0]
for i in range(1, len(nums)):
dp[i] = max(dp[i-1] + nums[i],nums[i])
res = max(res, dp[i])
return res
4.392.判断子序列
这道题的思路是求出s和t的最长公共子序列的长度,与s的长度进行比较,如果相等则返回True。与求有删减的最长公共子序列长度的区别在于递推关系式。对于s[j-1] != t[i-1]的情况,t可以回退但是s不用。dp[i][j] = dp[i-1][j]。
class Solution(object):
def isSubsequence(self, s, t):
"""
:type s: str
:type t: str
:rtype: bool
"""
dp = [[0] * (len(s)+1) for _ in range(len(t)+1)]
for i in range(1, len(t)+1):
for j in range(1, len(s)+1):
if t[i-1] == s[j-1]:
dp[i][j] = dp[i-1][j-1]+1
else:
dp[i][j] = dp[i-1][j]
if dp[-1][-1] == len(s):
return True
return False