求最大子数组之和:动态规划

156 阅读2分钟

思路

  • 暴力解法
    • 分别遍历给定输入的数组的每一项,通过i访问每一项(0≤i<n),在第一层遍历下,再遍历第二层,通过j访问每一项(j===i+1,j<n)
    • 在第二层遍历中,每次遍历当前第i项后的所有子项的时候,都去更新一下最终将要返回的最大子数组之和(maxSum)
    • 由于我的代码设计原因,需要单独给nums数组长度为1的时候做下判断,直接返回nums[0]
  • 动态规划
    • 由于我们只需要找到连续一段连续子项的最大和,所以我们在遍历给定输入数组的时候,可以以当前值的前面子项所代表的和值是否负数作为关键的判断条件,如果当前值的前面的值的和为负数,那么就什么也不做,从当前值重新开始。如果当前值的前面子项所代表的和值大于0,则把当前值的前面的子项所代表的和值加到当前值,反之什么也不做,继续遍历当前值的下一个值,以此类推,最终整个数组中的最大值就是我们原数组中的最大的子数组和

题目

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组

是数组中的一个连续部分。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:

输入:nums = [1]
输出:1

示例 3:

输入:nums = [5,4,-1,7,8]
输出:23

提示:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104

进阶: 如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。

代码1:暴力解法

/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function(nums) {
    let maxSum = 0;
    let n = nums.length;
    if(n === 1) return nums[0]

    for(let i = 0;i <  n;i++) {
       let  sum = nums[i];
        for(let j = i+1;j<n;j++){
            sum+=nums[j];
            maxSum = Math.max(maxSum,sum)
        }
    }

代码2:动态规划

/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function(nums) {
    for(let i = 1;i<nums.length;i++){
        if(nums[i - 1] <= 0) continue;
        else {
            nums[i] = nums[i] + nums[i - 1]
        }
    }
    return nums.sort((a,b)=>b-a)[0]

};