53. 最大子序和|刷题打卡

272 阅读2分钟

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… 处获得。