Leetcode演算法——53、子陣列的最大和
阿新 • • 發佈:2018-12-10
給定一個整數陣列,找到連續子陣列(至少包含一位)的最大和,並返回。
示例:
Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
思路
1、分治法
nums 的連續子陣列的最大和,就等於以下三者中的最大值:
- nums[:mid] 的連續子陣列的最大和
- nums[mid+1:] 的連續子陣列的最大和
- 包含nums[mid] 的連續子陣列的最大和
其中,mid 為中位數位置。
時間複雜度的遞推公式:T(n) = 2*T(n/2) + n
可求出:T(n) = O(nlogn)
2、動態規劃法
已知前 k 項的最大子陣列之和,求前 k+1 項的最大子陣列之和,就等於以下兩者的較大值:
- 前 k 項的最大子陣列之和
- 包含 nums[k] 的最大子陣列之和
其中第2步,包含 nums[k] 的最大子陣列之和,又可以根據前 k 項中包含 nums[k-1] 的最大子陣列之和來得到,只需要O(1)。
因此整體時間複雜度為 O(n)。
python實現
def maxSubArray(nums):
"""
:type nums: List[int]
:rtype: int
分治法。
"""
# 遞迴結束條件
l = len(nums)
if l == 1:
return nums[0]
# 求取包含nums[mid] 的連續子陣列的最大和
mid = l // 2
max_sum1 = 0 # mid 左半部分的最大和(從末尾向前累加)
cur_sum = 0
for num in nums[:mid][::-1]:
cur_sum += num
max_sum1 = max(max_sum1, cur_sum)
max_sum2 = 0 # mid 右半部分的最大和(從起始向後累加)
cur_sum = 0
for num in nums[mid+1:]:
cur_sum += num
max_sum2 = max(max_sum2, cur_sum)
max_sum = nums[mid] + max_sum1 + max_sum2
# 返回三者的最大值
return max(max_sum, maxSubArray(nums[:mid]), maxSubArray(nums[mid+1:]))
def maxSubArray2(nums):
"""
:type nums: List[int]
:rtype: int
動態規劃法
"""
sub_max = nums[0] # 儲存前i項的最大子陣列之和
last_max = nums[0] # 儲存前i項的且包含最後一位的最大子陣列之和
for i in range(1, len(nums)):
last_max = max(last_max + nums[i], nums[i])
sub_max = max(sub_max, last_max)
return sub_max
if '__main__' == __name__:
nums = [-2,1,-3,4,-1,2,1,-5,4]
print(maxSubArray2(nums))