- 任務
- 1143. 最長公共子序列
- 思路
- 1035. 不相交的線
- 思路
- 53. 最大子陣列和
- 思路
- 392. 判斷子序列
- 思路
- 1143. 最長公共子序列
任務
1143. 最長公共子序列
給定兩個字串 text1 和 text2,返回這兩個字串的最長 公共子序列 的長度。如果不存在 公共子序列 ,返回 0 。
一個字串的 子序列 是指這樣一個新的字串:它是由原字串在不改變字元的相對順序的情況下刪除某些字元(也可以不刪除任何字元)後組成的新字串。
例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。
兩個字串的 公共子序列 是這兩個字串所共同擁有的子序列。
思路
同718. 最長重複子陣列,只是這裡將連續的陣列換成了不連續的子序列,dp[i][j]表示 nums1 以i-1結尾,num2 以j-1結尾的最長公共子序列
相等時同樣用dp[i-1][j-1]+1來擴充長度。
區別是在當前不相等時,用兩陣列前一個索引所表示dp的較大值來保持已有長度。
class Solution:
def longestCommonSubsequence(self, text1: str, text2: str) -> 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[len(text1)][len(text2)]
1035. 不相交的線
在兩條獨立的水平線上按給定的順序寫下 nums1 和 nums2 中的整數。
現在,可以繪製一些連線兩個數字 nums1[i] 和 nums2[j] 的直線,這些直線需要同時滿足:
nums1[i] == nums2[j]
且繪製的直線不與任何其他連線(非水平線)相交。
請注意,連線即使在端點也不能相交:每個數字只能屬於一條連線。
以這種方法繪製線條,並返回可以繪製的最大連線數。
思路
完全是上題LCS的變形,不贅述。
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[len(nums1)][len(nums2)]
53. 最大子陣列和
給你一個整數陣列 nums ,請你找出一個具有最大和的連續子陣列(子陣列最少包含一個元素),返回其最大和。
子陣列是陣列中的一個連續部分。
思路
dp[i] 是以索引i為結尾的最大和,它為
- 之前的連續最大和加上自己
- 自己重新開始記錄
兩者的最大值
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
dp = [0] * len(nums)
dp[0] = nums[0]
result = dp[0]
for i in range(1,len(nums)):
dp[i] = max(nums[i],dp[i-1]+nums[i])
result = max(result,dp[i])
return result
392. 判斷子序列
給定字串 s 和 t ,判斷 s 是否為 t 的子序列。
字串的一個子序列是原始字串刪除一些(也可以不刪除)字元而不改變剩餘字元相對位置形成的新字串。(例如,"ace"是"abcde"的一個子序列,而"aec"不是)。
思路
是LCS的變形,只要兩個字串的最長公共子序列的長度為子序列s的長度,說明s是t的子序列,否則則不是。
class Solution:
def isSubsequence(self, s: str, t: str) -> bool:
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] = max(dp[i][j-1],dp[i-1][j])
return True if dp[len(s)][len(t)] == len(s) else False