53. 最大子序和(題目源地址)
給定一個整數數組 nums ,找到一個具有最大和的連續子數組(子數組最少包含一個元素),返回其最大和。
示例:
輸入: [-2,1,-3,4,-1,2,1,-5,4],
輸出: 6
解釋: 連續子數組 [4,-1,2,1] 的和最大,爲 6。
方法一:
貪心法
從左往右掃描,計算從下標爲0到當前位置子序列最大和與當前子序列的較大值, 然後再與全局最大值相比較,得到新的全局最大值
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
n = len(nums)
curr_sum = max_sum = nums[0]
for i in range(1, n):
curr_sum = max(nums[i], curr_sum + nums[i])
max_sum = max(max_sum, curr_sum)
return max_sum
方法二:
動態規劃法
從左往右掃描,用一個數組記錄當前位置下(從左往右子序列和的最大值), 然後取所有位置下記錄值的最大值,如下:
輸入: [-2,1,-3,4,-1,2,1,-5,4]
記錄: [-2,1,-2,4,3,5,6,1,5]
最大值爲6,則結果爲6
備註:當前值加上左邊的子序列的最大值若大於當前值,則說明左邊存在一個子序列加上當前值爲最大序列和。
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
sums = [0] * len(nums)
length = len(sums)
for i in range(length):
sums[i] = max(nums[i] + sums[i-1], nums[i])
return max(sums)
思考了一下覺得可以直接在nums上更新,當前位置的最大子序列和,可以省去外部的內存開銷。
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
for i in range(1, len(nums)):
nums[i] = max(nums[i] + nums[i-1], nums[i])
return max(nums)
方法三:
分治法
參考了官方的解題思路,這裏就不詳細介紹了,感興趣的可以直接點進去看,設計的還是非常巧妙的
class Solution:
def cross_sum(self, nums, left, right, p):
if left == right:
return nums[left]
left_subsum = float('-inf')
curr_sum = 0
for i in range(p, left - 1, -1):
curr_sum += nums[i]
left_subsum = max(left_subsum, curr_sum)
right_subsum = float('-inf')
curr_sum = 0
for i in range(p + 1, right + 1):
curr_sum += nums[i]
right_subsum = max(right_subsum, curr_sum)
return left_subsum + right_subsum
def helper(self, nums, left, right):
if left == right:
return nums[left]
p = (left + right) // 2
left_sum = self.helper(nums, left, p)
right_sum = self.helper(nums, p + 1, right)
cross_sum = self.cross_sum(nums, left, right, p)
return max(left_sum, right_sum, cross_sum)
def maxSubArray(self, nums):
return self.helper(nums, 0, len(nums) - 1)
今天打卡完成!明天再接再厲!