leetcode每天一题:【最大子数组和】(简单)

114 阅读1分钟

这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战

题目描述

leetcode题目地址

给一个整数数组,需要你找出这个数组的子数组的最大和,并返回它。并且子数组长度至少要大于0。

补充:子数组必须在数组是连续的

补个例子:

arr: [1, -1, 2, -3]
结果: 21 + -1 + 2arr: [-1, 3, 2, 2]
结果: 73 + 2 + 2arr: [12]
结果: 31 + 2

思路分析

第一种方法

因为是求最大子数组之和,这个我们可以利用Math.max方法,定义两个变量

pre = 0,这个是记录数组遍历的时候,数组累加值和当前遍历的数比较,大的就赋值给pre,默认是0。

res = nums[0], 这个记录当前的最大值,默认是数组的第一个。

对数组进行遍历,遍历的数逐级累加,然后和当前遍历的数比较,

  • 如果当前遍历的数大,就赋值给pre,代表这个是最大子数组和的第一项
  • 如果累加的值大,也赋值给pre,代表当前累加值大

然后把preres比较

  • 如果比res大就把覆盖之前res,赋值给它。
  • 如果比res小则无需操作,还是维持现状,res的大。

这样能保证截止目前遍历,res拿到的就是目前最大子数组的和。

最后res拿到的就是最大子数组的和。

代码如下:

/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function (nums) {
  let pre = 0;
  let res = nums[0];
  for (let i = 0; i < nums.length; i++) {
    pre = Math.max(nums[i], nums[i] + pre)
    res = Math.max(pre, res)
  }
  return res
}

image.png

第二种方法:

其实跟第一种方法的思路是一致的,只不过把Math.max的写法换成if判断,可能会相对好理解一点。

对数组进行遍历,如果目前累加的值小于0,则证明无论是否加上当前遍历的值,都会比当前遍历的值小,所以,直接替换累加的值。否则继续累加。

目前累加值和res判断,如果大于res,则替换之前的res。

最后的res就是最大子数组的和。

/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function (nums) {
  let pre = 0;
  let res = nums[0];
  for (let i = 0; i < nums.length; i++) {
    if (pre < 0) pre = nums[i]
    else pre += nums[i]
    if (pre > res) res = pre
  }
  return res
};

image.png