算法简单题,吾辈重拳出击 - 连续子数组的最大和

Posted 掘金安东尼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法简单题,吾辈重拳出击 - 连续子数组的最大和相关的知识,希望对你有一定的参考价值。

技术题目无罪,不要让不好的面试体验干涉到技术学习上来。

是的,算法题是绝对有它本身价值的!

算法简单题,吾辈重拳出击

对算法感到畏惧的 xdm,咱不求一口吃个胖子,先对算法简单题重拳出击,尝试建立自信,训练基础算法思维,不日定能大杀四方、所向披靡。

OK,闲言少叙,上题:

这是一道经典题:# ​​剑指 Offer 42. 连续子数组的最大和​

输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。

要求时间复杂度为O(n)。

示例1:

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

这题的基础算法思维是:动态规划(Dynamic programming,简称DP)

  • 老观众都知道之前在讲狄克斯特拉最短路径问题有提过这个,有兴趣去专栏翻一翻。

DP的操作过程,一言以蔽之:大事化小,小事化了。 即将一个大问题转化成几个小问题;求解小问题;推出大问题的解。

解:

1、题目要求的是给出连续最大子数组和是多少,而没有要求给出连续最大子数组是哪一个。明白这一点很重要。

2、其次,题目要求了,时间复杂度要是 O(n) ,所以只能用一次遍历。

3、接着,最关键的是,怎么理解“连续最大”。“连续最大数组的特点是什么?”答案是:

  • 连续最大的数组的最后一位肯定是一个正数,要不然还把它纳入进来干嘛?
  • 然后,这个正数前面的几个数字之和也要是正数!要不然还要它前面的纳入干嘛?

有了上面的认识,我们用一层 for 循环,用 sum 变量来收集当前遍历的数字前面数字的最大和,如果这个最大和大于0,则加上当前遍历数字,如果这个最大和小于0,则让最大和直接等于正在遍历的数字。最终的结果 res 在上一轮的最大和和这一轮的计算后的最大和中取最大值。

比如数组是 [-2,1,3,-4,5]:res 初始值为 nums[0],即为 -2;

开始遍历:

[-2],sum = -2 res = -2

[-2,1] sum 在上一轮为 -2,小于 0 ,此时,最大和等于 1,供下一轮判断使用 ,res = max(-2,1)

[-2,1,3] sum 在上一轮为 1,大于 0,此时最大和等于 1+3=4,res = max(1,4)

[-2,1,3,-4] sum 在上一轮为 4 ,大于0,此时最大和等于 4-4=0,res= max(4,0)

[-2,1,3,-4,5] sum 在上一轮为 0, 等于0,此时最大和等于 0+5=5,res=max(4,5)

所以:

如果 ​​sum > 0​​,则说明 sum 对结果有增益效果,则 sum 保留并加上当前遍历数字

如果 ​​sum <= 0​​,则说明 sum 对结果无增益效果,需要舍弃,则 sum 直接更新为当前遍历数字

每次比较 ​​sum​​ 和 ​​res​​的大小,将最大值置为​​res​​,遍历结束返回结果

代码实现:

/**
* @param number[] nums
* @return number
*/
var maxSubArray = function(nums)
let res = nums[0];
let sum = 0;
for(const num of nums)
sum > 0 ? sum+=num : sum = num
res = Math.max(res, sum);

return res;
;

小结:

本题,思路很重要。想明白给的条件的引申解释123点,再跟着示例去走一遍,代码中的 DP 思路就很好理解了~


OK,以上便是本篇分享。点赞关注评论,为好文助力

以上是关于算法简单题,吾辈重拳出击 - 连续子数组的最大和的主要内容,如果未能解决你的问题,请参考以下文章

算法简单题,吾辈重拳出击 - 动态规划之爬楼梯

算法leetcode|面试题 04.02. 最小高度树(rust重拳出击)

算法leetcode|面试题 04.02. 最小高度树(rust重拳出击)

算法leetcode|1967. 作为子字符串出现在单词中的字符串数目(rust和go重拳出击)

算法leetcode|1967. 作为子字符串出现在单词中的字符串数目(rust和go重拳出击)

算法leetcode2317. 操作后的最大异或和(rust和go重拳出击)