有四种解决方法:
- 直接暴力解决
- Kadane 算法
- 动态规划
- 分治算法
1、暴力解决
从头开始遍历整个数组中的数,并且进行组合,共有n(n+1)/2 种连续子数组,因此此选择方法需要的时间复杂度为O(n2)
2、Kadane 算法
- 第i+1个数结尾的子列和= max(以第i个数结尾的子列和+nums[i+1],nums[i+1])
- 使用递归 (迭代)从第一项开始计算得到每个i结尾的最大子列和
- 比较得到最后的结果
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
max_end_here = 0
max_so_far = nums[0]
for i in range(len(nums)):
if max_end_here + nums[i] < nums[i]:
max_end_here = nums[i]
else:
max_end_here += nums[i]
if max_so_far < max_end_here:
max_so_far = max_end_here
return max_so_far
来源:https://blog.csdn.net/the__apollo/article/details/77367534
3、分治的方法
这个问题可以分成三个子问题来思考,以中间为分界,求出左边的最大子序列和(max_left), 右边最大子序列和(max_right), 以及跨越中间的最大子序列和(max_cross).
跨越中间的最大子序列,可以使用挨着中间数(mid)左边的最大序列和加上挨着中间数(mid) 右边最大的序列和之和。
求着三个序列中的最大者则为最大子序列和。
整个算法的流程:
FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high):
left-sum = -inf
sum = 0
for i = mid downto low
sum = sum + A[i]
if sum > left-sum
left-sum = sum
max-left = i
right-sum = -inf
sum = 0
for j = mid+1 to high`在这里插入代码片`
sum = sum + A[j]
if sum > right-sum
right-sum = sum
max-right = i
return (max-left, max-right, left-sum+right+sum)
来源:https://www.cnblogs.com/jclian91/p/9151120.html
算法实现(拖了一个星期的我终于写完了我哭)
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
length =len(nums) -1
return self.maxsub(0, length, nums)
def maxsub(self, lo, hi, nums):
if hi < lo:
return None
if hi==lo:
return nums[lo]
if hi - lo == 1:
return self.max_of_three(nums[lo], nums[hi]+nums[lo], nums[hi])
mid = int((lo + hi)/2)
max_l = self.maxsub(lo, mid, nums)
max_r = self.maxsub(mid, hi, nums)
max_cross = self.maxCross(lo, hi, mid, nums)
return self.max_of_three(max_l, max_r, max_cross)
def maxCross(self, lo, hi, mid, nums):
i_l = i_r = mid
v_l = v_r = nums[mid]
v_l_tmp = v_r_tmp = nums[mid]
while lo < i_l:
v_l_tmp += nums[i_l-1]
if v_l <= v_l_tmp:
v_l = v_l_tmp
i_l -= 1
while i_r < hi:
v_r_tmp += nums[i_r+1]
if v_r <= v_r_tmp:
v_r = v_r_tmp
i_r += 1
return self.max_of_three(v_l, v_l + v_r-nums[mid], v_r)
def max_of_three(self, l, mid, r):
max_v = l
if max_v < mid:
max_v = mid
if max_v < r:
max_v = r
return max_v