一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情。
老规矩先看题目:
53、给你一个整数数组 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 <= 105-104 <= nums[i] <= 104
[1]、动态规划(DP)
我们去建立一个叫做“尝试变量”的变量,也就是代码中的now,(假设从头开始,数组最少两个元素)
(也就是从第一个元素开始算子序列和)
它的尝试就在于now先加上数组的第一个元素,再去加上第二个元素,用现在now的值和第二个元素相比,
如果now值比第二个元素要小,我们就把now的值更新为第二个元素的值,因为如果now加上了第二个元素
的值还比第二个元素小就证明,第一个元素是我们的“累赘”会“拖累”我们求最大子序列,所以干脆舍弃掉
第一个元素,从第二个元素开始算子序列和,然后用一个max()函数来更新一下我们最后的结果值即可。
class Solution {
public:
int maxSubArray(vector<int>& nums)
{ int Size=nums.size();
//这里是之前说过,是因为因为nums.size()返回的是无符号数,和整数判断容易出错,所以转换一下整形
int res=INT_MIN;
//在做这一类统计总和之前要用到max()函数的时候,最好要把这个变量定义为整形的最小值
int now=0;
for(int i=0;i<Size;i++){
now+=nums[i];//如上面解释所说
if(now<nums[i]) now=nums[i]; //从现在第i个元素开始算序列和
res=max(res,now); //用max()更新一下res(结果值)
}
return res; }
};
[2]、贪心算法其实贪心和动态规划有一点不同,但出入也不是很大,想法类似,唯一不同的点在于是用
sum<0这个条件去重新查找子序列
int maxSubArray1(vector<int>& nums)
{
//类似寻找最大最小值的题目,初始值一定要定义成理论上的最小最大值
int result = INT_MIN;
int numsSize = int(nums.size());
int sum = 0;
for (int i = 0; i < numsSize; i++)
{
sum += nums[i];
result = max(result, sum);
//如果sum < 0,重新开始找子序串
if (sum < 0)
{
sum = 0;
}
}
return result;
}
顺带最后说一下,这个用暴力法解不出来,会超过时间限制。