53. 最大子序和|刷题打卡
create by db on 2021-3-6 00:12:29
Recently revised in 2021-3-6 00:22:35
闲时要有吃紧的心思,忙时要有悠闲的趣味
原题链接53. 最大子序和
题目描述
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例 1:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
示例 2:
输入:nums = [1]
输出:1
示例 3:
输入:nums = [0]
输出:0
示例 4:
输入:nums = [-1]
输出:-1
示例 5:
输入:nums = [-100000]
输出:-100000
提示:
- 1 <= nums.length <= 3 * 104
- -105 <= nums[i] <= 105
进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。
思路分析
思路一:
首先我们可以统计所有的累加和,取最大值。这是最简单暴力的解法,毫无难度,目标就是覆盖每一种情况,我们可以叫他——穷举。
思路二:
不知你有没有看出来一个规律:当累加结果小于当前值的时候,我们就可以丢弃累加结果,取当前值。
这种找规律的做法叫做动态规划
AC 代码
题解一:穷举
var maxSubArray = function(nums) {
// 假设数组有 abcd 四个元素,遍历顺序为正向(i: 0~n,j: i~n),即:
// i=0) a、ab、abc、abcd
// i=1) b、bc、bcd
// i=2) c、cd
// i=3) d
let len = nums.length
if (len === 0) return nums
let res = nums[0]
// 暴力双重遍历,范围为 i:0~n, j:i~n
for (let i=0; i<len; i++) {
let tmp = nums[i]
for (let j=i; j<len; j++) {
if (i!==j) tmp += nums[j]
res = Math.max(res, tmp)
}
}
return res
};
题解二:动态规划
/**
* @param {number[]} nums
* @return {number}
*/
var maxSubArray = function(nums) {
if (nums.length === 0) return nums
// 定义当前总和,以及最大总和
let sum = 0, maxSum = nums[0]
nums.forEach(el => {
// 取当前总和及当前值的最大值
sum = Math.max(sum + el, el)
// 取当前总和及最大总和最大值
maxSum = Math.max(sum, maxSum)
})
return maxSum
};
总结
三月你好,春暖花开。加油!
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情
后记:Hello 小伙伴们,如果觉得本文还不错,记得点个赞或者给个 star,你们的赞和 star 是我编写更多更丰富文章的动力!GitHub 地址
文档协议
db 的文档库 由 db 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。
基于github.com/danygitgit上的作品创作。
本许可协议授权之外的使用权限可以从 creativecommons.org/licenses/by… 处获得。