每日一题:Leetcode 53.最大子序和

(fei)(hua)

书接上回,自从张小胖同学成功AC了Leetcode 1.两数之和这道题后,便觉得自己特别牛批。这天,他又信心满满地来到了Leetcode题库,准备大战一番。这时,一行“最长子序列和”突然映入张小胖的眼帘:

题目描述:

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

示例:

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

进阶:
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。

题解:

题目难度:简单
解题思路
“最长子序列和?”小胖不禁嘴角上扬。要知道,这道题可是一道超级经典的入门题。只见小胖稍加思索,心中便已经有了主意。

//方法一:暴力法 时间复杂度:O(n^3)
func maxSubArray(nums []int) int {
	max := -2147483647
	var sum int
	for l := 0 ; l<len(nums) ; l ++ {
		for r := l ; r<len(nums) ; r ++ {
			for t := l ; t<=r ; t ++{
				sum+=nums[t]
			}
			if sum > max {
				max = sum
			}
			sum = 0
		}
	}
	return max
}

“既然是求最长子列和,那么我只要列举出主列中的所有子列,并找出所有子列和的最大值不就可以了?”小胖得意地彪呼呼地交了上去。突然,一道光芒刺瞎了小胖的狗眼:

在这里插入图片描述果不其然超时了,时间复杂度高达O(n^3)的暴力算法就是不一般,果然没有经受住Leetcode测评姬的考验 。小胖骂骂咧咧地看着题目中的测试样例,陷入了沉思。

2-43-12-43 //答案4(选3、-1、2)

“我们看到这行数列,确实能够轻松地推出它的最大子列和是4,那么答案是怎么推出来的呢?”小胖边想,边把推理过程写了下来:

首先看到第一个数,是2,2后面是-4,所以如果-4是最优子列的一部分,那么2一定也在其中(答案就增加了)

随后是3,如果3把前面的2和-4加上去,结果是1。这个时候反而比原来的3要小了。所以如果答案含有3,就一定不会加上前面的2和-4。

下一个数是-1。这个数加上前面的3之后增加了数值(变成了2),所以如果答案有-1,辣么绝对还有前面的3。

接下来是2,如果2加上前面的序列(3、-1),辣么它的值变为4。比原先增加了。

然后是-4,如果把-4加上前面的序列(3、-1、2),结果会变成0,比原先的-4大,所以如果-4是答案的一部分,那么前面的三个数也一定是答案的一部分。

最后一个数,也就是3,如果将3加上前面的序列,结果变成了3。最后我们来看一看刚推导的结果,发现4是我们可以得出的最大和,故输出4。

如果针对此题,我们便不难发现以下推论:
第一个数为一个有效序列。如果一个数加上上一个有效序列得到的结果比这个数大,那么该数也属于这个有效序列(接纳这个数进入有效序列)。 如果一个数加上上一个有效序列得到的结果比这个数小,那么这个数单独成为一个新的有效序列(上一个有效序列完全拖后腿,所以直接抛弃掉)。

“推导完毕。“小胖长舒一口气,感叹道:”原来我们的大脑在不知不觉中运用了动态规划的思想。那还等什么,俺滴键盘已经迫不及待了!”说罢小胖哗哗一顿乱敲:

//方法2:动态规划法,时间复杂度O(n)
func maxSubArray(nums []int) int {
	if len(nums) < 2 {
		return nums[0]
	}
	var temp int
	res := -2147483647
	for i := 0 ; i < len(nums); i ++ {
		if nums[i] > temp + nums[i] {
			temp = nums[i]
		} else {
			temp = temp+nums[i]
		}
		if temp > res {
			res = temp
		}
	}
	return res
}

终于AC了,小胖露出了欣慰的笑容。

所谓动态规划,就是把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解的过程。在本样例中,我们正是利用了动态规划的思想,把求解长度为7的主列中最大子列和的问题转化为求解一条长度为1的主列中最大子列和的问题,时时刻刻让当前状态的局部子列和处于最优,并不断扩充主列长度,直至长度为7。换句话说,我们如果在第6个数、第5个数…第n个数就停下来的话,那时所求得的最大子列和依然是对于前n个数的最优解!这恰恰说明动态规划思想满足‘最优化原理’和‘无后效性’的特性。

PS:关于题目中所提到的分治法,各位读者朋友有思路了吗?

本文引用博客链接:https://www.luogu.com.cn/blog/Walker-68145/solution-p1115
原题目链接:https://leetcode-cn.com/problems/maximum-subarray

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值