【算法】最大连续子数组 (暴力法、分治法、分析法、动态规划法)
2015-04-17 16:14
399 查看
最大连续子数组 (暴力法、分治法、分析法、动态规划法)
给定一个数组A[0,…,n-1],求A的连续子数组,使得该子数组的和最大。
例如
数组: 1, -2, 3, 10, -4, 7, 2, -5,
最大子数组:3, 10, -4, 7, 2
1、 暴力法(时间复杂度O(n3))
直接求解A[i,…j]的值
0≤ i < n
i≤ j < n
class Solution: ''' 暴力法,时间复杂度O(n3) @param nums:an integer[] @return: an integer ''' def maxSubArray(self,nums): maxsum=0 begin=0 end=0 for i in range(8): for j in range(i,8): tempsum=sum(nums[i:j+1]) #子数组的和 if tempsum>maxsum: maxsum=tempsum begin=i end=j return begin,end,maxsum,nums[begin:end+1] if __name__ == '__main__': solution=Solution() nums=[1, -2, 3, 10, -4, 7, 2, -5] print solution.maxSubArray(nums)
2、分治法(时间复杂度O(nlogn))
class Solution: ''' 分治法 @param nums:an integer[] @return: an integer ''' def maxSubArray(self,nums): begin=0 end=len(nums)-1 if begin==end: return nums[begin] middle=(begin+end)/2 m1=self.maxSubArray(nums[begin:(middle+1)]) m2=self.maxSubArray(nums[(middle+1):(end+1)]) #中间分别向左和向右扫描找到最大后缀和最大前缀 left=nums[middle] now=nums[middle] for i in range(middle-1,begin-1,-1): now+=nums[i] left=max(left,now) right=nums[middle+1] now=nums[middle+1] for i in range(middle+2,end+1,1): now+=nums[i] right=max(right,now) m3=left+right return max(m1,m2,m3)
3、 分析法(时间复杂度O(n))
算法过程
1. 求i前缀p[i]:
遍历i:0≤i ≤n-1
p[i]=p[i-1]+A[i]
2. 计算p[i]-p[j]
遍历i:0≤i ≤n-1,求最小值m
m的初值取0(P[-1]=0),然后遍历p[0…i-1],更新m
p[i]-m即为以a[i]结尾的数组中最大的子数组
3. 在第2步中,可顺手记录p[i]-m的最大值。
class Solution: ''' 分析法 @param nums:an integer[] @return: an integer ''' def maxSubArray(self,nums): #计算前i项的和 n=len(nums) p=[] p.append(nums[0]) m=0 maxsum=p[0]-m for i in range(1,n): p.append(p[i-1]+nums[i]) if m>p[i-1]: m=p[i-1] if maxsum<p[i]-m: maxsum=p[i]-m return maxsum
4、动态规划法(O(n))
记S[i]为以A[i]结尾的数组中和最大的子数组
则:S[i+1] = max(S[i]+A[i+1], A[i+1])
S[0]=A[0]
遍历i: 0≤i ≤n-1
class Solution: ''' 动态规划 @param nums:an integer[] @return: an integer ''' def maxSubArray(self,nums): result=nums[0] sum=nums[0] for num in nums[1:]: if sum>0: sum+=num else: sum=num if sum>result: result=sum return result
参考
july4月算法 邹博PPT
相关文章推荐
- 《github一天一道算法题》:分治法求数组最大连续子序列和
- 《github一天一道算法题》:分治法求数组最大连续子序列和
- 【算法】最大连续子数组和
- 求连续子数组最大和,两种算法
- 算法笔记_043:最大连续子数组和(Java)
- 分治法:求给定数组A[1:n]的最大连续子数组
- 经典算法——连续子数组最大和问题
- 笔试算法题(06):最大连续子数组和 & 二叉树路径和值
- 最大连续子数组(分治法、动态规划)
- 最大连续子数组和(算法导论算法实现)
- 【算法】_011_最大子数组_暴力法
- [算法导论]练习4.1-5最大连续子数组问题
- 给定一个由非负整数和整数m组成的数组,可以将该数组分成m个非空的连续子数组。 写一个算法来最小化这些m个子阵列之间的最大和。
- c/c++ 算法之求连续子数组的最大和
- 【算法】_012_最大子数组_分治法
- 每日一算法:求连续子数组和的最大值
- 算法学习-最大连续子数组
- 第四章 分治策略 4.1 最大子数组问题 (暴力求解算法)
- 分治法求连续子数组的最大和