leetCode刷题日记——53题 最大子序和

在这里插入图片描述

1.贪心算法

贪心算法核心在于子问题的划分,并且尽可能的完成子问题的最优解。

1)确定最优解,最优解其实就是尽量把大的数拿上,但是他们又得连续。
2)划分子问题。从左往右开始拿数,贪心要求我们每次拿都要是有增长的,没增长的就去掉,没增长的就是前面拿了的比0还要小,我加上反而自己变得更小,所以此时扔掉前面拿到的,重新开始拿。这就好比你一路借钱,有人借给你有人直接给你钱,你还有机会“赖账”,那还不每次借完钱转头就忘,接着借下一家,否则你还等着拿了别人白给你的钱还债?(纯举例,狗头)

此题需要注意的地方:
我是在每个子问题上力求拿到最大的和,因此抛弃已经成为负数的和,但是有可能这个和之前是最大的,比如说:
数组{1,99,-101,1}
在到数组第三个元素之前,和是100,妥妥最大和,但是加上-101它变成负数了,必须要扔掉了,否则一个负数加上任何数都只会让和变得更小。
所以一定要记录子问题中产生的最大和,我们划分的子问题要靠比较才能找出最优解。

此题思路目前就清晰了:
1.记录上一次和,如果为负数了就丢弃。
2.记录过程中最大的和。
3.遍历一次数组。

代码如下:

class Solution {
    public int maxSubArray(int[] nums) {
    	int lastSum = nums[0];
    	int maxSum = nums[0];
    	for (int i = 1; i < nums.length; i++) {
    		if(lastSum<0) {
    			lastSum = nums[i];
    		}else {
    			lastSum += nums[i];
    		}
    		if(lastSum>maxSum) {
    			maxSum = lastSum;
    		}
		}
		return maxSum;
    }
    
}

2.动态规划

动态规划解决问题首先要具有两个条件:
1.具有子结构
2.可以通过重叠子结构解决问题。

我个人的理解是建模列出一个对子结构的处理公式,然后记录下子结构处理结果得出最终结果。

本题动态规划有一个特别之处,将以某个元素结尾的最大和为:f(i)
其中i为数组下标。
f(i) = max{f(i-1)+num[i],f(i)}
这个公式的意思就是有两种情况:
1)前面的最大和加上这个元素就是以这个元素结尾的最大值
2)否则就是这个元素自己是最大和(想想,如果前面全是负的,加上只能更小,此时元素本身就是最大了即f(i))

我个人对动态规划的理解就是找到递归关系,将递归转化为递推,核心在于用空间换时间,用一个数组什么的记录下来每一个子结构产生的结果。

	// 使用动态规划
	public static int maxSubArray2(int[] nums) {
		int maxSum = nums[0];
		int sum[] = new int[nums.length];
		sum[0] = nums[0];
		if (nums.length > 1) {
			//sum[i]中储存的是以i位置元素结尾的连续子数组的最大值,而sum[i+1] = max{sum[i]+num[i+1],num[i+1]}
			for (int i = 1; i < nums.length; i++) {
				//这个地方为了和贪心算法做区分所以才比较了大小实际判断条件可以写为
				//if (sum[i - 1] + nums[i] >0)
				if (sum[i - 1] + nums[i] > nums[i]) {
					sum[i] = sum[i - 1] + nums[i];
				} else {
					sum[i] = nums[i];
				}
				if (sum[i] > maxSum) {
					maxSum = sum[i];
				}
			}
		}
		return maxSum;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值