leetcode-005-最大子序和
刷题之旅从数组类型的题目开始。第五道题目是移除元素,对应leetcode的题号为53。
题目描述
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
1 | 输入: [-2,1,-3,4,-1,2,1,-5,4], |
解题思路
这道题目可以利用贪心算法的思想来解决,时间复杂度为O(n),所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,它所做出的仅仅是在某种意义上的局部最优解。
那么我们可以从头开始往后试,定义一个值叫sum,这个sum专门来计算连续子数组的和,因为贪心嘛,追求的是最好每次sum都在逐渐增加,但是呢,实际上我又不能每次都管增加的,有的时候会适当下降是为了下一个元素的猛增。因此其实也不贪心,标准设置为0,只要sum不小于0我就一直往后加,一旦小于0,那么此时sum包含的子数组串已经失去意义了,就从新的位置重新计算sum。在这过程中,一直与最大值做比较,从而在局部的最优解中逐渐获取到全局最优解。代码如下:
1 | class Solution { |
此题其实是动态规划的典型题目(上面个代码是用贪心角度来说的,其实吧,跟下面的动态规划也没啥大区别,不过姑且分开吧,因为动态规划是有其强烈的自身标识的,即可以用一个表达式来表达出求解规律)
1 | dp[i] 定义为数组nums 中已num[i] 结尾的最大连续子串和, 则有: |
其实就是说,【前面比较的结果+当前值】与【当前值】做比较,谁大就取谁。其实跟上面所谓的贪心思路是不是差不多?实际上,这种看起来思路是清晰一点的,掌握了动态规划还是可以写出来的,不过上面的贪心是需要一定的功力才能写出来(我觉得)。
用一个临时数组来存放遍历过程中的最大值,最后取这个临时数组最大值即可,时间复杂度O(n),空间复杂度O(n):
1 | class Solution { |
其实不需要数组,因为我们可以发现,我们每次只关心dp数组的最后一个有效值,因此我们想办法用一个变量把最后一个有效值保存下来即可。见最终提交代码:
提交代码
1 | class Solution { |