题目:Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array [−2,1,−3,4,−1,2,1,−5,4]
,
the contiguous subarray [4,−1,2,1]
has the largest sum = 6
.
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
o(n)的方法比较简单,即是依次遍历数组,记录目前求和值与最大值:若当前数为负数,则计算加上其后的求和值,与最大值进行比较,若大于最大值则更改最大值,其后,将求和值归零,以下一个值为片段的开始;若当前数非负,则只需比较加上其后的求和值与最大值,若求和值大于最大值,则更改最大值。代码如下:
class Solution:
# @param A, a list of integers
# @return an integer
def maxSubArray(self, A):
L=len(A)
rs=0
m=A[0]
for i in range(0,L):
rs+=A[i]
if rs<0:
if rs>m:
m=rs
rs=0
else:
if rs>m:
m=rs
return m
divide and conquer的方法,即归并,算法复杂度为o(nlogn),计算式为 T(n)=2*T(n/2)+o(n)
采用递归调用,以数组片段的中间点为分界线,判断该中间点是否包括在最终所求的数组片段内,因此需要比较三个值的大小:包含中间点的最大和值,不包含中间点的最大和值(即左数组片段的最大和值,右数组片段的最大和值),选择其中最大的值作为结果返回。
后两值采用函数递归调用即可得到;
而在求包含中间点的最大和值,需要找到向左延伸的上界和向右延伸的下界。因此,以中间点为起点向左求和,最大值的初始值设为中间点的值,如果当前和值大于最大值,则修改最大值;同理,以中间点右边一点为起点向右求和,最大值的初始值设为该点的值,如果当前和值大于最大值,则修改最大值,将两个最大值相加,即可得到包含中间点的最大和值。具体的代码如下:
class Solution:
# @param A, a list of integers
# @return an integer
def maxSubArray(self, A):
def maxS(A,left,right):
if left==right: return A[left]
middle=(left+right)/2
leftm=maxS(A,left,middle)
rightm=maxS(A,middle+1,right)
lm=A[middle]
rm=A[middle+1]
t=0
for i in range(middle,left-1,-1):
t+=A[i]
if(t>lm):
lm=t
t=0
for i in range(middle+1,right+1):
t+=A[i]
if(t>rm):
rm=t
return max(leftm,rightm,lm+rm)
L=len(A)
return maxS(A,0,L-1)