小白js硬啃leetcode算法-最大子序和(数组简单-53)-2

101 阅读2分钟

题目

53、给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和 你可以按任意顺序返回答案
范例: 输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6

动态规划

  • 动态规划扫盲
    • 以本题为例,我们对于求最大子序(假设为[a,b,c,d]),最初想到的是取到所有连续数组合的情况,然后从中取最大值
    • 通常的取组合情况,会有以下三种方式
      1. 节点从左到右取所有情况,即a节点所有组合[a], [a,b], [a,b,c], [a,b,c,d] ,以b节点所有组合[b]...
      2. 节点从右到左取所有情况,即d节点所有组合[d], [c,d], [b,c,d], [a,b,c,d],以c节点所有组合[c]...
      3. 以组合个数作为基准取,即数组长度为1[a], [b], [c], [d],长度为2[a, b]...
    • 遍历特点
      1. 方式1通常用户暴力解法
      2. 方式2通常可以产生递进关系,因为后一个节点x所有情况即是x-1点所有情况加上x[x]的组合。这是动态规划的常用思路
      3. 组合情况暂时没有遇到,以后遇到补充。。。
  • 解题思路:
    • 题目取最大子序合,即需要将数组连续组合取最大值,我们可以借用上方的方法2进行拆分
    • 假设数组为[a,b,c],拆分为取各个节点的所有组合的最大值(假设为f(a)[a]中最大值, f(b)[b], [a,b]中最大值)
    • 求出各个节点最大值后,比较这些最大值取其中最大值作为结果返回
    • 根据上述思路我们可以进行如何下推论
      1. ab的关系, a节点所有情况值加上b节点值以及b节点即为b节点所有组合
      2. f(a)f(b)关系,f(b) = Math.max(f(a) + b,b)
      3. f(n)f(n-1)关系,f(n) = Math.max(f(n-1) + num_n ,num_n)(n为任意值第n个数,num_n为n节点值)
  • 复杂度
    • 时间复杂度:O(n)
    • 空间复杂度: O(1)
const maxSubArray = function(nums) {
    let maxSum = Math.max(...nums)
    let nowSum = 0
    if( maxSum > 0 ){ // 所有值为负不需要进行计算 
       nums.forEach( num=>{
         nowSum = Math.max( num,  nowSum + num  )
         maxSum = Math.max(maxSum, nowSum)
      })
    }
    return maxSum
};

题目来源:力扣(LeetCode)
链接:leetcode-cn.com/problems/ma…