Leetcode刷题(18) 最大自序和, 最长递增子序列,最大....
这两道题较为类似,dp数组的定义比较特别,转移方程也很相似。
方法参考labuladong的动态规划设计:最大子数组和动态规划设计:最长递增子序列
53. 最大子序和
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
n = len(nums)
res = -float('Inf')
if n < 0:
return 0
# dp数组含义: 以 nums[i] 为结尾的「最大子数组和」为 dp[i]
dp = [0] * n
dp[0] = nums[0]
# 循环(状态)
for i in range(1, n):
# 接着上一个dp[i-1], 还是自立门户(做选择)
dp[i] = max(dp[i-1] + nums[i], nums[i])
# 得到以那个i结尾的最大子数组和大
for i in range(n):
res = max(res, dp[i])
return res
# ===============================================================
# 空间压缩
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
n = len(nums)
if n < 0:
return 0
dp_0 = nums[0]
res = dp_0
dp_1 = 0
# 循环(状态)
for i in range(1, n):
# 接着上一个dp[i-1], 还是自立门户(做选择)
dp_1 = max(dp_0 + nums[i], nums[i])
res = max(dp_1, res)
dp_0 = dp_1
return res
128. 最长连续序列
哈希辅助
class Solution:
def longestConsecutive(self, nums):
longest_streak = 0
# hash辅助
num_set = set(nums)
for num in num_set:
if num - 1 not in num_set:
# num-1不在的话就可以以num为起点开始记录连续值
cur_num = num
# 开始匹配以当前值为起点的连续值
l = 0
while cur_num in num_set:
l += 1
cur_num += 1
# 更新最大值
longest_streak = max(l, longest_streak)
return longest_streak
快慢指针迭代法
class Solution(object):
def longestConsecutive(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums = sorted(list(set(nums)))
if len(nums) == 0:
return 0
start = 0
pre_end = 0
end = 1
l = 1 # 无论什么情况,只要list不是空的,都至少有1的连续
while end < len(nums):
# 发生断裂, start跳到当前的end
if nums[end] - nums[pre_end] > 1:
# 在当前位置重置
start = end
pre_end = end
else:
# 连续, 更新l
l = max(l, end - start + 1)
pre_end += 1
end += 1
return l
718. 最长重复子数组
动态规划
class Solution(object):
def findLength(self, A, B):
"""
:type A: List[int]
:type B: List[int]
:rtype: int
"""
na = len(A)
nb = len(B)
# 用一个变量跟踪记录全局的最大值
res = 0
dp = [[0] * (nb + 1) for _ in range(na + 1)]
for i in range(1, na + 1):
for j in range(1, nb + 1):
# 连续相同 +1
if A[i-1] == B[j-1]:
dp[i][j] = dp[i-1][j-1] + 1
res = max(dp[i][j], res)
# 阶段 重置为0
else:
dp[i][j] = 0
return res
128. 最长连续序列
迭代法
class Solution(object):
def longestConsecutive(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums = sorted(list(set(nums)))
if len(nums) == 0:
return 0
n = len(nums)
start = 0
# end的前驱
pre = 0
l = 1 # 无论什么情况,只要list不是空的,都至少有1的连续
for end in range(1, n):
# 断裂
if nums[end] - nums[pre] > 1:
# start跳到end上
start = end
pre = end
# 接上了
else:
l = max(l, end - start + 1)
pre = end
return l
哈希辅助法
class Solution:
def longestConsecutive(self, nums):
if len(nums) == 0:
return 0
num_set = set(nums)
# 在前进(+1)的路上已经遇到过的数就不要计算了
visited = []
l_max = 1
for num in num_set:
# num-1在的话就没有必要处理num, 遍历到num-1的时候处理num-1就行啦
if num - 1 not in num_set and num not in visited:
cur_num = num
l = 1
while cur_num + 1 in num_set:
cur_num = cur_num + 1
l += 1
l_max = max(l, l_max)
return l_max