字串与子序列系列问题
最大子串和
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
ans, pre_sum = -1e4 - 1, 0
for i in nums:
if pre_sum < 0: pre_sum = 0
pre_sum += i
ans = max(ans, pre_sum)
return ans
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int pre = 0, ans = nums[0];
for (const auto &x: nums) {
pre = max(pre + x, x);
ans = max(ans, pre);
}
return ans;
}
};
无重复字符的最长子串
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
visit, ans, l, start = {}, 0, len(s), -1
for i in range(l):
if s[i] in visit: start = max(start, visit[s[i]])
ans = max(ans, i - start)
visit[s[i]] = i
return ans
最长递增子序列
\(dp[i]\) 表示以 \(nums[i]\) 结尾的最长递增子序列长度为 \(dp[i]\), \(O(n^2)\) 时间复杂度度.
class Solution(object):
def lengthOfLIS(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
dp, l = [], len(nums)
for i in range(l):
dp.append(1)
for j in range(i):
if nums[i] > nums[j]: dp[-1] = max(dp[-1], dp[j] + 1)
return max(dp)
\(dp[i]\) 表示长度为 \(i\) 的最长递增子序列的最后一位的最小值情况为 \(dp[i]\), \(O(n\log n)\) 时间复杂度度.
class Solution(object):
def lengthOfLIS(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
dp, l = [], len(nums)
for i in range(l):
if len(dp) == 0 or nums[i] > dp[-1]: dp.append(nums[i])
else:
l, r, loc = 0, len(dp) - 1, len(dp) - 1
while l <= r:
mid = (l + r) // 2
if dp[mid] < nums[i]: l = mid + 1
else: loc, r = mid, mid - 1
dp[loc] = nums[i]
return len(dp)
编辑距离
对单词 A 删除一个字符和对单词 B 插入一个字符是等价的, 只考虑插入与修改两个操作即可.
class Solution(object):
def minDistance(self, word1, word2):
"""
:type word1: str
:type word2: str
:rtype: int
"""
m, n = len(word1), len(word2)
dp = [[505 for i in range(n + 1)] for j in range(m + 1)]
for i in range(m + 1): dp[i][0] = i
for i in range(n + 1): dp[0][i] = i
for i in range(1, m + 1):
for j in range(1, n + 1):
if word1[i - 1] == word2[j - 1]:
dp[i][j] = min(dp[i][j], dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1])
else:
dp[i][j] = min(dp[i][j], dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + 1)
return dp[m][n]