原题描述:
给定一个整数数组 nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
解答:
1. 暴力搜索---时间复杂度O(n^3),空间复杂度O(1)
这个解答是超过本题要求的复杂度的,所以并不能AC
class Solution { public int maxSubArray(int[] nums) { int sum = nums[0]; int ans = 0; for(int i = 0;i < nums.length ; ++i){ for(int j = i;j < nums.length;++j){ ans = 0; for(int m = i;m <= j;++m){ ans += nums[m]; } if(ans > sum){ sum = ans; } } } return sum; } }
2. 优化枚举:两重循环---时间复杂度O(n^2),空间复杂度O(1)
在这里,主要对于子序数组加和部分做了改进。节省了一重循环的时间复杂度。
class Solution { public int maxSubArray(int[] nums) { int sum = nums[0]; int ans = 0; for(int i = 0;i < nums.length ; ++i){ ans = 0; for(int j = i;j < nums.length;++j){ ans += nums[j]; if(ans > sum){ sum = ans; } } } return sum; } }
3. 继续优化---时间复杂度O(n),空间复杂度O(1)
这里是在ans < 0情况下做了优化,如果ans < 0,那直接把ans设成0,也就是在加和的时候不算之前小于0的部分子序了,但需要返回结果的变量sum中其实也存了现有的最大值,所以不用担心全复数数组这种情况。
class Solution { public int maxSubArray(int[] nums) { int sum = nums[0],ans = 0; int n = nums.length; for(int i = 0;i < n;++i){ ans = ans + nums[i]; sum = Math.max(ans , sum); if(ans < 0) ans = 0; } return sum; } }
4. 分析最短用时代码
这里的思想和复杂度其实都是一样的,可能测试用例不太一样所以时间也不同吧。
class Solution { public int maxSubArray(int[] nums) { int length = nums.length; if(length==0){ return 0; } int sum = nums[0]; int b = 0; for(int i=0;i<length;i++){ if(b>0){ b += nums[i]; }else{ b = nums[i]; } if(sum<b){ sum = b; } } return sum; } }