题目:给定一个整数数组 nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
解法一:暴力破解法 时间复杂度O(N^3) 超时
这是我们最容易想到的,通过枚举暴力破解,但是时间复杂度过高,算法运行超时。
def maxSubArray1(nums):
maxnum = pow(-2, 31)#最小的整数
for i in range(len(nums)):
for j in range(i,len(nums)):
sumnum = 0
for k in range(i,j+1):
sumnum += nums[k]
if sumnum > maxnum:
maxnum = sumnum
return maxnum
解法二:改进暴力破解法 时间复杂度O(N^2) 依然超时,看来题目要求是O(N)的时间复杂度
def maxSubArray2(nums):
maxnum = pow(-2, 31) # 最小的整数
for i in range(len(nums)):
sumnum = 0
for j in range(i, len(nums)):
sumnum += nums[j]
if sumnum > maxnum:
maxnum = sumnum
return maxnum
解法三:扫描法O(N)
我们可以从正负数入手,当我们加上一个正数时,和会增加;当我们加上一个负数时,和会减少。所以我们需要判断当前的和是正数还是负数,如果是正数继续向下累加,如果是负数,应该抛弃当前数重新开始加和。(据说这个算法是一个统计学家提出的,证明)
def maxSubArray3(nums):
current = nums[0] # 设置的初始值
sum = 0
for i in range(len(nums)):
if sum > 0:
sum += nums[i]
else:
sum = nums[i]
if sum > current:
current = sum
return current
解法四:
动态规划知识点
定义:Dynamic programming is a method for solving a complex problem by breaking it down into a collection of simpler subproblems,solving each of those subproblems just once,and storing their solutions.
基本思想:一般来说,只要问题可以划分为规模更小的字问题,并且原问题的最优解中包含了子问题的最优解,则可以考虑用动态规划解决。动态规划的实质是分治思想和解决冗余。因此,动态规划是一种将问题实例分解为更小的/相似的子问题,并存储子问题的解,使得每个子问题只求解一次,最终获得原问题的答案,以解决最优化问题的算法策略。
思想:我们遍历nums数组,求出对应下标的最大连续子数组的和,并且保存在nums数组中。假设nums[i]是以第i个元素结尾的最大的连续子数组的和,这样对于i之前的元素对应的最大连续子数组的长度都已经求得了。我们只需要判断nums[i] + nums[i-1] 是否大于nums[i],将两者中较大的值作为nums[i]的值即可。如此迭代,即可得到整个数组每个元素对应的最大连续子数组和。
def maxSubArray4(nums):
length = len(nums)
for i in range(1,length):
subMaxSum = max(nums[i] + nums[i-1],nums[i])
nums[i] = subMaxSum
return max(nums)
参考链接:
1、https://blog.csdn.net/zwzsdy/article/details/80029796
2、https://blog.csdn.net/qq_27480345/article/details/86095087
3、https://blog.csdn.net/iva_brother/article/details/84037050