Given an integer array nums
, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.
给定一个整数数组nums,找到nums拥有最大和的连续子数组,返回这个和
Example:
Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
Follow up:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
Solutions:
本题是很经典的一道题目,在剑指offer上也有出现,目的是求解连续的最大和子数组。
本题可以用动态规划的方法做,我们暂时先放下动态规划的思路,用普通的思想求解这道题目。
整体的思路如下:
声明两个记录连续子数组和的变量,cursum用来记录当前的连续子数组的和,totalsum用来记录全局连续子数组的和,并用cursum来更新totalsum。
以剑指offer上的题目为例:[1,-2,3,10,-4,7,2,-5],初始化和cursum为0。第一步加上第一个数字1,此时和为1。接下来第二步加上数字-2,和变成-1。第三步加上数字3,我们注意到由于此前累计的和是-1,小于0,那么如果用-1加上3,得到的和是2,比3本身还要小,这就说明从第一个数字加到3之前的连续数字其实是无效的,还不如直接以3为起点。因此我们不考虑从第一个数字开始的子数组,之前的累积和丢弃,转而以3为连续最大和的起始位置。
我们从第三个数字开始累加,此时得到的和是3。接下来加10,得到13。第五步加上-4,和为9。我们发现由于-4是一个负数,因此累加-4之后得到的和比原来的和还要小,我们需要把之前得到的13保存下来,即存入totalsum中,它有可能是最大的连续子数组的和。第六步9加数字7,得16,此时16大于13,我们把子数组和由13更新为16。第七步加上2,再对累加和更新到18,最后我们累加-5,发现和为13,小于之前的18,则不做最大和更新
Python
(1)
class Solution:
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
totalsum = float('-inf') #totalsum中保存全局的最大和Python中正负无穷表示为:float('inf')和float('-inf')
cursum = 0 #cursum用来保存当前的和
for i in nums:
if cursum >= 0: #当cursum大于0时,叠加i
cursum += i
else: #当cursum小于0时,重新选定起始点,重新开始寻找cursum
cursum = i
if cursum >= totalsum: #用cursum更新totalsum,即用当前和更新最大和,当前和大于最大和时更新
totalsum = cursum
return totalsum
(2)
class Solution:
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
for i in range(1, len(nums)):
if nums[i-1] > 0:
nums[i] += nums[i-1]
return max(nums)
C++
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int size = nums.size();
//该方法将i前面的最大连续子数组的和存在了nums[i]中,最后选出nums中最大的元素,即为最大的连续子数组和;
//nums的index最大到size-1,所以i<size-1,i最大到size-2
for(int i = 0;i<size-1;i++){
if (nums[i]>0){
nums[i+1] += nums[i];
}
}
return *max_element(nums.begin(),nums.end());
}
};