LeetCode53. 最大子数组和

Tomorrowland 2024-07-25 08:39:01 阅读 100

题目链接:https://leetcode.cn/problems/maximum-subarray/description/

题目叙述:

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组是数组中的一个连续部分。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]

输出:6

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

示例 2:

输入:nums = [1]

输出:1

示例 3:

输入:nums = [5,4,-1,7,8]

输出:23

提示:

1 <= nums.length <= 10^5

-104 <= nums[i] <= 10^4

暴力思路:

这题暴力思路十分简单,枚举出每一组的数组子序列,取最大值即可

暴力思路代码如下:

class Solution {

public:

int maxSubArray(vector<int>& nums) {

int result = INT32_MIN;

int count = 0;

for (int i = 0; i < nums.size(); i++) { // 设置起始位置

count = 0;

for (int j = i; j < nums.size(); j++) { // 每次从起始位置i开始遍历寻找最大值

count += nums[j];

result = count > result ? count : result;

}

}

return result;

}

};

不过暴力解法肯定超时了!

贪心思想:

贪心贪的是哪里呢?

如果 -2 1 在一起,计算起点的时候,一定是从 1 开始计算,因为负数只会拉低总和,这就是贪心贪的地方!

局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。

全局最优:选取最大“连续和”

局部最优的情况下,并记录最大的“连续和”,可以推出全局最优。

从代码角度上来讲:遍历 nums,从头开始用 count 累积,如果 count 一旦加上 nums[i]变为负数,那么就应该从 nums[i+1]开始从 0 累积 count 了,因为已经变为负数的 count,只会拖累总和。

这相当于是暴力解法中的不断调整最大子序和区间的起始位置。

那么我们只需要遍历一次数组,当count一旦小于0了,就把count赋值为0,直接从下一位开始加,否则就会拖累正的数字!

代码如下:

class Solution {

public:

int maxSubArray(vector<int>& nums) {

int result=INT_MIN;

int count=0;

for(int i=0;i<nums.size();i++){

count+=nums[i];

//及时更新最大值

if(count>result) result=count;

//如果count小于0,直接从下一位开始

if(count<0) count=0;

}

return result;

}

};



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。