最长连续子序和问题

2020-03-28  本文已影响0人  madao756

0X00 算法总结

最大子序和

53. 最大子序和

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        if len(nums) == 0: return 0

        m = len(nums)

        # dp 问题以结尾分集合
        # dp[i] 表示以 i 结尾的最大连续子序和
        dp = [0] * 2
        dp[0] = nums[0]
        ans = dp[0]
        for i in range(1, m):
            n = nums[i]
            dp[i & 1] = max(dp[(i-1) & 1]+n, n)
            ans = max(ans, dp[i & 1])
        
        return ans

这是一道非常经典的 dp 问题, 以最大子序和的最后一个数字来划分集合

转移方程:

窗口大小限制的最大子序和

135. 最大子序和

n, m = map(int, input().split())
nums = list(map(int, input().split()))

sums = [0] * (n+1)

for i in range(1, n+1):
    sums[i] = sums[i-1] + nums[i-1]

from collections import deque

# print(sums)

deq = deque([0])

res = sums[1]
for i in range(1, n+1):
    if i - m > deq[0]: deq.popleft()
    res = max(res, sums[i] - sums[deq[0]])
    while len(deq) > 0 and sums[i] <= sums[deq[-1]]:
        deq.pop()
    deq.append(i)
print(res)

用「单调队列」来解决这一方面的问题

使用「前缀合」以后发现固定最后一位, 减去前面前不超过窗口大小的最小的一位, 就是以 i 结尾的最大子序列和

上一篇下一篇

猜你喜欢

热点阅读