[路飞]_程序员必刷力扣题: 53. 最大子数组和

108 阅读1分钟

「这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战

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 = [5,4,-1,7,8]
输出: 23

提示:

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

暴力求解

思路

直接双循环,分别求出从i到j的所有结果,每次比较i到j的和与最大值max的值,重新赋值max 最后直接返回max即可

具体实现:

  • 双循环外层i开始,内层j=i开始;

*我们这里使用滚动数组的方式,用一个curr记录下上次计算的结果,接下来j++的时候,curr = curr + nums[i]

  • 比较max与curr的大小

最后返回max

时间复杂度n2超时

var maxSubArray = function (nums) {
    var len = nums.length;
    var curr = null;
    var max = null;
    for (var i = 0; i < len; i++) {
        for (var j = i; j < len; j++) {
            if (i === j) {
                curr = nums[i]
            } else {
                curr = curr + nums[j]
            }
            // 给max赋值
            if (max !== null) {
                max = Math.max(curr, max)
            } else {
                max = curr
            }
        }
    }
    return max;
};

贪心

思路 贪心的核心思想是:如果当前元素之前的元素和为负数,那么就可以直接丢弃了,因为任何数与负数相加都只会更小。

具体实现:

  • 直接定义当前值curr = nums[0],max=curr
  • 从i=1开始遍历nums,判断curr(当前元素之前的元素和)的值
    • curr小于0为负数,直接舍弃curr,curr从新赋值为当前值
    • curr大于0,那么正常累加
  • 比较curr和max的大小,保留较大值 最后直接返回max即可
var maxSubArray = function (nums) {
    // 贪心
    var len = nums.length;
    var curr = nums[0];
    var max = curr;
    for (var i = 1; i < len; i++) {
        if(curr<0){
            curr = nums[i]
        }else{
            curr = curr + nums[i]
        }
        max = Math.max(curr,max)
    }
    return max;
};

动态规划

思路 动态规划的思路和贪心类似,如果之前的元素和为负数则当前值不做任何处理,也是舍弃负数的结果,如果前一个元素值大于0才会加在当前元素上

具体实现:

  • 直接从i = 1开始遍历nums,判断nums的前一位i-1的值
    • 如果i-1位负数则当前i无需处理
    • 如果i-1位正数,则当前值为i-1加上nums[i]的值 最后我们在整个nums数组中取最大值

返回最大值即可

var maxSubArray = function (nums) {
    // 动态规划
    var len = nums.length;
    for (var i = 1; i < len; i++) {
        if(nums[i-1]>0){
            nums[i] = nums[i-1] + nums[i]
        }
    }
    return Math.max(...nums);
};