@author: sdubrz
@date: 2020.03.30
题目难度: 简单
考察内容:动态规划
原题链接 https://leetcode-cn.com/problems/maximum-subarray/
题目的著作权归领扣网络所有,商业转载请联系官方授权,非商业转载请注明出处。
解题代码转载请联系 lwyz521604#163.com
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
解法
这道题是《算法导论》第三版中用于讲分治算法的一个例子,分治算法的复杂度为O(nlogn),其课后题中有线性时间复杂度的方法。下面只是简单地说一下,具体分析可参考第三版的《算法导论》第4章。
我在系统提交的时候,用的是线性复杂度的方法,这种方法的代码量也相对少一点。主要的思路是:对于一个数组的最大子数组,在这个最大子数组有多于两个元素的情况下,任意将这个最大子数组切分为前后两部分,这两部分各自的和必然是正的。这部分应该比较好理解,因为如果有一部分的和是负的或0,我们可以把这部分删掉,剩下的部分的和一定不小于原来的子数组。最大子数组的左右两部分的和都是正的,也就意味着左右两部分的和都要小于总的和。基于这个思路,可以写出如下代码
class Solution {
public int maxSubArray(int[] nums) {
int tempLeft = 0;
int tempRight = 0;
int left = 0;
int right = 0;
int sum = nums[0];
int maxSum = nums[0];
for(int i=1; i<nums.length; i++){
if(sum+nums[i]>nums[i]){
sum = sum + nums[i];
tempRight = i;
}else{
sum = nums[i];
tempLeft = i;
}
if(maxSum<sum){
maxSum = sum;
left = tempLeft;
right = tempRight;
}
}
return maxSum;
}
}
在LeetCode系统中提交的结果:
执行结果:通过
执行用时 : 1 ms, 在所有 Java 提交中击败了 97.36% 的用户
内存消耗 : 42.1 MB, 在所有 Java 提交中击败了 5.40% 的用户