Q2-最大子序和-LeetCode53

思路:贪心算法,每次碰到当前元素sum<0,直接更新sum的值,之前的值全部抛弃,但是问题是如果所有的输入都是负数,该怎么处理呢?


int maxSubArray(vector<int>& nums) {
	int sum = 0;
	int max_ = 0;
	int minus = INT_MIN;
	bool flag = true;		//默认只有负数
	for (int i : nums) {
		if (i < 0&& flag) {
			if(i > minus)
			minus = i;
		}
		else {
			flag = false;
			sum += i;
			sum = max(0, sum);
			max_ = max(max_, sum);
		}
	}
	return (flag==true?minus:max_);
}

 注意看我操作(*^▽^*).

使用一个标记位flag来标记当前是否全部都是负数,如果遇到了正数,就更改flag的值,如果都是负数,取最大的那个负数.但是不能写成下面这样

if(i<0&&flag&&i>minus) { minus=i}
else{
    ...
}

不然比如我先遍历-2,再遍历-1,会进入到else中,导致最后输出的结果是0,而不是要求的最大负数!

第二方法:动态规划.

int maxSubArray(vector<int>& nums) {
	int *dp =new int[nums.size()+1];		//dp[i]表示说以这个元素结尾的最大子序和,但是并不是从头到尾的最大
	memset(dp, 0, sizeof(dp));
	dp[0] = nums[0];
	int much=nums[0];
	for (int i = 1; i < nums.size(); ++i)
	{
		dp[i] = max(nums[i], dp[i-1] + nums[i]);			//选择加入这个nums[i]或者重新选择一个nums[i],舍弃之前选择的元素
		much = max(dp[i], much);
	}
	return much;
}

借助于贪心思想,我们不断选取当前元素和到之前i-1项的最大dp值中的最大值.需要说明的是,我们需要记录max(dp[i]).

因为dp[i]表示的是说不论如何nums[i]一定会被选取的规则,所以我们并不是说从0~n-1项的最大子序和,而是说包含了当前元素的最大子序和!

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shallow_Carl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值