Leetcode Day 38 - DP: Subsequence
1143 Longest Common Subsequence | 1035 Uncrossed Lines | 53 Maximum Subarray | 392 Is Subsequence
Dynamic Programming
Diff | Problem | Python | Java |
---|---|---|---|
1143 Longest Common Subsequence | ✅ | ||
1035 Uncrossed Lines | ✅ | ||
53 Maximum Subarray | ✅ | ||
392 Is Subsequence | ✅ |
Longest Common Subsequence
Given two strings text1
and text2
, return the length of their longest common subsequence. If there is no common subsequence, return 0
.
A subsequence of a string is a new string generated from the original string with some characters (can be none) deleted without changing the relative order of the remaining characters.
For example, "ace"
is a subsequence of "abcde"
. A common subsequence of two strings is a subsequence that is common to both strings.
Example 1
1
2
3
Input: text1 = "abcde", text2 = "ace"
Output: 3
Explanation: The longest common subsequence is "ace" and its length is 3.
Example 2
1
2
3
Input: text1 = "abc", text2 = "abc"
Output: 3
Explanation: The longest common subsequence is "abc" and its length is 3.
Example 3
1
2
3
Input: text1 = "abc", text2 = "def"
Output: 0
Explanation: There is no such common subsequence, so the result is 0.
Solution
A detailed explaination of solution can be found here[^lcsSolution].
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution(object):
def longestCommonSubsequence(self, text1, text2):
text1, text2 = list(text1), list(text2)
n1 = len(text1)
n2 = len(text2)
dp = [[0] * (n2 + 1) for _ in range(n1 + 1)]
result = 0
for t1 in range(1,n1 + 1):
for t2 in range(1,n2 + 1):
temp = max(dp[t1][t2 - 1], dp[t1 - 1][t2])
if dp[t1 - 1][t2 - 1] < temp:
dp[t1][t2] = temp
else:
dp[t1][t2] = dp[t1 - 1][t2 - 1]
if text1[t1 - 1] == text2[t2 - 1]:
dp[t1][t2] += 1
if dp[t1][t2] > result: result = dp[t1][t2]
return result
Use scrolling arrays to increase efficiency
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution(object):
def longestCommonSubsequence(self, text1, text2):
n1, n2 = len(text1), len(text2)
# 确保使用较短的字符串进行列计算,以节省空间
if n1 < n2:
text1, text2 = text2, text1
n1, n2 = n2, n1
# 滚动数组优化空间,只保留前一行和当前行
prev = [0] * (n2 + 1)
curr = [0] * (n2 + 1)
for i in range(1, n1 + 1):
for j in range(1, n2 + 1):
if text1[i - 1] == text2[j - 1]:
curr[j] = prev[j - 1] + 1
else:
curr[j] = max(prev[j], curr[j - 1])
# 交换 prev 和 curr
prev, curr = curr, prev
# 结果在最后一行
return prev[n2]
Uncrossed Lines
You are given two integer arrays nums1
and nums2
. We write the integers of nums1
and nums2
(in the order they are given) on two separate horizontal lines.
We may draw connecting lines: a straight line connecting two numbers nums1[i]
and nums2[j]
such that:
nums1[i] == nums2[j]
, and- the line we draw does not intersect any other connecting (non-horizontal) line.
Note that a connecting line cannot intersect even at the endpoints (i.e., each number can only belong to one connecting line).
Return the maximum number of connecting lines we can draw in this way.
Example 1
1
2
3
4
Input: nums1 = [1,4,2], nums2 = [1,2,4]
Output: 2
Explanation: We can draw 2 uncrossed lines as in the diagram.
We cannot draw 3 uncrossed lines, because the line from nums1[1] = 4 to nums2[2] = 4 will intersect the line from nums1[2]=2 to nums2[1]=2.
Example 2
1
2
Input: nums1 = [2,5,1,2,5], nums2 = [10,5,2,1,5,2]
Output: 3
Example 3
1
2
Input: nums1 = [1,3,7,1,7,5], nums2 = [1,9,2,5,1]
Output: 2
Solution
A detailed explaination of solution can be found here[^ulSolution].
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution(object):
def maxUncrossedLines(self, nums1, nums2):
n1, n2 = len(nums1), len(nums2)
if n1 < n2:
nums1, nums2 = nums2, nums1
n1, n2 = n2, n1
prev = [0] * (n2 + 1)
curr = [0] * (n2 + 1)
for i in range(1, n1 + 1):
for j in range(1, n2 + 1):
if nums1[i - 1] == nums2[j - 1]:
curr[j] = prev[j - 1] + 1
else:
curr[j] = max(prev[j], curr[j - 1])
prev, curr = curr, prev
return prev[n2]
Maximum Subarray
Given an integer array nums, find the subarray with the largest sum, and return its sum.
Example 1
1
2
3
Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
Output: 6
Explanation: The subarray [4,-1,2,1] has the largest sum 6.
Example 2
1
2
3
Input: nums = [1]
Output: 1
Explanation: The subarray [1] has the largest sum 1.
Example 3
1
2
3
Input: nums = [5,4,-1,7,8]
Output: 23
Explanation: The subarray [5,4,-1,7,8] has the largest sum 23.
Solution
A detailed explaination of solution can be found here[^msSolution]. A detailed explaination of greedy solution can be found here.
Python
1
2
3
4
5
6
7
8
9
10
class Solution:
def maxSubArray(self, nums):
cur_num = nums[0]
result = cur_num
for i in range(1, len(nums)):
cur_num = max(cur_num + nums[i], nums[i])
if cur_num > result: result = cur_num
return result
Is Subsequence
Given two strings s
and t
, return true
if s
is a subsequence of t
, or false
otherwise.
A subsequence of a string is a new string that is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (i.e., "ace"
is a subsequence of "abcde"
while "aec"
is not).
Example 1
1
2
Input: s = "abc", t = "ahbgdc"
Output: true
Example 2
1
2
Input: s = "axc", t = "ahbgdc"
Output: false
Solution
A detailed explaination of solution can be found here[^isSolution].
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution(object):
def isSubsequence(self, s, t):
ls = len(s)
if ls == 0: return True
target = 0
for j in range(len(t)):
if t[j] == s[target]:
target += 1
if target == ls: return True
return False
Reference
](https://leetcode.com/problems/longest-common-subsequence/description/). [^lcsSolution]:代码随想录-最长公共子序列: https://programmercarl.com/1143.最长公共子序列.html. [^ul]:Leetcode-1035 Uncrossed Lines: https://leetcode.com/problems/uncrossed-lines/description/. [^ulSolution]:代码随想录-不相交的线: https://programmercarl.com/1035.不相交的线.html. [^ms]:Leetcode-53 Maximum Subarray: https://leetcode.com/problems/maximum-subarray/description/. [^msSolution]:代码随想录-最大子序和: https://programmercarl.com/0053.最大子序和(动态规划).html. [^is]:Leetcode-392 Is Subsequence: https://leetcode.com/problems/is-subsequence/description/. [^isSolution]:代码随想录- https://programmercarl.com/0392.判断子序列.html.
Leetcode-1143 Longest Common Subsequence: [https://leetcode.com/problems/longest-common-subsequence/description/ ↩︎