对于给定的整数数组nums,找出该数组中累加和最大的连续整数串,并返回其最大和
Example:
Input: [-2,1,-3,4,-1,2,1,-5,4], Output: 6 Explanation: [4,-1,2,1] has the largest sum = 6.
进阶:
如果已经实现时间复杂度为O(n)的解决方法,可以尝试用更为精妙的分治法解决该问题
1:动态规划DP,时间复杂度O(n)的方法,参考(https://www.cnblogs.com/springfor/p/3877058.html)
这道题要求 求连续的数组值,加和最大。
试想一下,如果我们从头遍历这个数组。对于数组中的其中一个元素,它只有两个选择:
1. 要么加入之前的数组加和之中(跟别人一组)
2. 要么自己单立一个数组(自己单开一组)
所以对于这个元素应该如何选择,就看他能对哪个组的贡献大。如果跟别人一组,能让总加和变大,还是跟别人一组好了;如果自己起个头一组,自己的值比之前加和的值还要大,那么还是自己单开一组好了。
所以利用一个sum数组,记录每一轮sum的最大值,sum[i]表示当前这个元素是跟之前数组加和一组还是自己单立一组好,然后维护一个全局最大值即位答案。
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:
return None
if len(nums)==1:
return nums[0]
cursum = nums[0]
maxsum = nums[0]
for num in nums[1:len(nums)]:
cursum = max(cursum+num,num)
maxsum = max(maxsum,cursum)
return maxsum
2:Kadane算法,时间复杂度O(n),参考(http://www.cnblogs.com/jclian91/p/9151120.html)
Kadane算法的简单想法就是寻找所有连续的正的子数组,同时,记录所有这些连续的正的子数组中的和最大的连续数组。每一次我们得到一个正数,就将它与最大的连续数组比较,如果它的值比最大的连续数组大,则更新最大的连续数组的值。
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:
return None
if len(nums) == 1:
return nums[0]
cursum = 0
maxsum = float("-inf")
for num in nums:
cursum += num
maxsum = max(maxsum,cursum)
if cursum<0:
cursum = 0
return maxsum
上面是 python 实现,下面是 java 实现的版本
public int maxSubArray(int[] nums) {
if (nums.length == 0) {
return 0;
}
if (nums.length == 1) {
return nums[0];
}
int curSum = nums[0]; // 当前最大连续子序列和
int maxSum = nums[0]; // 全局最大连续子序列和
for (int i = 1;i < nums.length;i++) {
if (curSum + nums[i] >= nums[i]) {
curSum += nums[i];
} else {
curSum = nums[i];
}
if (maxSum < curSum) {
maxSum = curSum;
}
}
return maxSum;
}
以下是 go 实现版本
func maxSubArray(nums []int) int {
if len(nums) == 0 {
return 0
}
if len(nums) == 1 {
return nums[0]
}
curSum := nums[0] // 当前最大连续子序列和
maxSum := nums[0] // 全局最大连续子序列和
for _, elem := range nums[1:] {
if curSum + elem >= elem {
curSum += elem
} else {
curSum = elem
}
if maxSum < curSum {
maxSum = curSum
}
}
return maxSum
}
算法题来自:https://leetcode-cn.com/problems/maximum-subarray/description/