算法学习-连续子数组求和最大值

PS:腾讯暑期实习二面居然就问了我这个,,,可惜最后还是跪了,唉?

来源于LeetCode第53题:

https://leetcode.com/problems/maximum-subarray/

1.最笨的办法-穷举法

思路就是,取出所有可能的子数组,即找出所有可能的0≤i≤j≤n,然后求出数组从i到j的所有数的和再对比,这样的方法时间复杂度较高,python实现如下:

 1 class Solution(object):
 2     def maxSubArray(self, nums):
 3         """
 4         :type nums: List[int]
 5         :rtype: int
 6         """
 7         n=len(nums);
 8         ans = -100000000000;
 9         for i in range(0,n):
10             sums = 0
11             for j in range(i,n):
12                 sums += nums[j];
13                 ans=max(ans,sums)
14         return ans

 

  

提示超时,最终执行的输入如下:

此时的时间复杂度为O(n^3)

2.第一次优化:

这一步求和的时候,每次没有必要从i到j完整求和,只要存储了上一次求和的结果,之后只要在前面求和的基础上继续累加就可以。

具体方法就是,把sums=0在j循环之前声明,j进行循环时,每次求和是在前一次求和的基础上再加上num[j]:

 

 1 class Solution(object):
 2     def maxSubArray(self, nums):
 3         """
 4         :type nums: List[int]
 5         :rtype: int
 6         """
 7         n=len(nums);
 8         ans = -100000000000;
 9         for i in range(0,n):
10             sums = 0
11             for j in range(i,n):
12                 sums += nums[j];
13                 ans=max(ans,sums)
14         return ans

 

此时超时的结果为,有提升:

 

时间复杂度此时为O(n^2)

3.第二次优化:贪心算法

计算某串子数组A[i:j],一旦发现sum(A[i:j])<0,那么后面A[i:j+1]之后就无需再计算了,这一组结果一定不满足最大(已经算出了负数,完全可以把这组负数结果抛弃掉,从下一个下标开始算),因此此时应该直接开始算从A[j+1]开始的子数列:
 1 class Solution(object):
 2     def maxSubArray(self, nums):
 3         """
 4         :type nums: List[int]
 5         :rtype: int
 6         """
 7         n=len(nums);
 8         ans = -100000000000;
 9         sums = 0;
10         for i in range(0,n):
11             sums = sums+nums[i]
12             ans = max(sums,ans)
13             if sums <= 0 :
14                 sums = 0;
15         return ans

结果通过!事实上,此次的时间复杂度只有O(n)

转载于:https://www.cnblogs.com/koliverpool/p/6445899.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值