您的位置:首页 > 编程语言 > Java开发

Java&LeetCode 初入门——053. 最大子序和

2019-01-08 20:00 218 查看

Java&LeetCode 初入门——053. 最大子序和


文内代码全部采用JAVA语言。

题目

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
示例:

输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

个人解法

本人表示本人太渣了,这题完全没想到如何降低复杂度,除了遍历还是遍历。个人代码以及长到超出时间限制,哭晕在厕所。以后还是要多学习才行。就不把我的代码贴出来丢人现眼了。直接学习大神们的解法吧。

大神解法

思路

其实有一个想法很好理解,就是当前面几个数的和小于0时,就没必要带上这几个数了,因为越带越小。比如[-1,-2,5,7,-3,-4,5],从前往后依次看,第一个读取的数是-1,虽然是负数,但没有读取下一个数之前,它是目前的最大值,放在res中。但是负数对于求和取最大值起到的是反作用,所以如果取下一个值的时候,还不如丢掉-1,直接取-2,也比(-1)+(-2)来的划算。第二个和值直接为-2,放在sum中,和res比较,取较大值放在res中。目前的sum依旧小于0,对和值没有帮助,第三个和值直接为5,放在sum中,和res比较,取较大值放在res中。以此类推。

其实简单来讲就是一个指针,从头指到尾。继续看[-1,-2,5,7,-3,-4,5],看指针前面的sum是不是大于0,大于0的sum的子序列对整个连续子数组的最大值有帮助。比如指针指到7时,7前面连续的最大的sum是5,那么整个连续子数组可以纳入5。小于0的sum对整个连续子数组的最大值起反作用,直接抛弃前面的sum。比如指针指到5时,前面的sum=-2,没有帮助,还不如不要,所以指针5时,连续子数组中只有[5]。

自己找个数组调试一遍,很快就能明白了。

算法

16 ms, 在Maximum Subarray的Java提交中击败了60.83% 的用户。
我觉得挺厉害的了,能想到这样的解法真是666(忽略我的垃圾水平)。

class Solution {
public int maxSubArray(int[] nums) {
int res = nums[0];
int sum = 0;
for (int num : nums) {
if (sum > 0)
sum += num;
else
sum = num;
res = Math.max(res, sum);
}
return res;
}
}

范例区最快的解法

class Solution {
public int maxSubArray(int[] nums) {
int sum = 0, max = Integer.MIN_VALUE;
for(int i = 0; i < nums.length; i++){
sum = sum<0? nums[i] : (sum+nums[i]);
max = Math.max(sum, max);
}
return max;
}
}

区别不大,只是在于max的初始值和一个三元运算符,思路基本一致。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐