这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战
题目描述
给一个整数数组,需要你找出这个数组的子数组的最大和,并返回它。并且子数组长度至少要大于0。
补充:子数组必须在数组是连续的
补个例子:
arr: [1, -1, 2, -3]
结果: 2(1 + -1 + 2)
arr: [-1, 3, 2, 2]
结果: 7(3 + 2 + 2)
arr: [1,2]
结果: 3(1 + 2)
思路分析
第一种方法
因为是求最大子数组之和,这个我们可以利用Math.max方法,定义两个变量
pre = 0,这个是记录数组遍历的时候,数组累加值和当前遍历的数比较,大的就赋值给pre,默认是0。
res = nums[0], 这个记录当前的最大值,默认是数组的第一个。
对数组进行遍历,遍历的数逐级累加,然后和当前遍历的数比较,
- 如果当前遍历的数大,就赋值给
pre,代表这个是最大子数组和的第一项 - 如果累加的值大,也赋值给
pre,代表当前累加值大
然后把pre和res比较
- 如果比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
}
第二种方法:
其实跟第一种方法的思路是一致的,只不过把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
};