js实现最大子序和--力扣

目录

1 问题

2 输入输出

3 解法

1)贪心方法

2)动态规划

3)动态规划空间优化

4 代码

1 问题

https://leetcode-cn.com/problems/maximum-subarray/

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

2 输入输出

示例:

输入: [-2,1,-3,4,-1,2,1,-5,4],

输出: 6

解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

3 解法

1)贪心方法

  步骤:

使用贪心策略,如果之前的和sum<=0,那么丢弃之前的项,更新sum为当前项;如果之前的sum >0, 更新sum为当前与原来sum之和。

而结果(最大子和)resultmax{sumresult}

 

-2

1

-3

4

-1

2

1

-5

4

当前值

-2

1

-3

4

-1

2

1

-5

4

之前和

null

-2

1

-2

4

3

5

6

1

当前和

-2

1

-2

4

3

5

6

1

5

最大值

-2

1

1

4

4

5

6

6

6

时间复杂度:O(n)

空间复杂度:O(1)

2)动态规划

子问题:「连续子数组的最大和」,如图

转移方程:如图

 

时间复杂度:O(n),其中 n nums 数组的长度。我们只需要遍历一遍数组即可求得答案。

空间复杂度:O(n)。我们只需要常数空间存放若干变量。

3)动态规划空间优化

时间复杂度:O(n),其中 n nums 数组的长度。我们只需要遍历一遍数组即可求得答案。

空间复杂度:O(1)。我们只需要常数空间存放若干变量。

4 代码

/**
 * @param {number[]} arr
 * @return {number}
 * 功能:数组最大子序列和
 * 贪心方法:如果当前元素之前和为负,则抛弃之前元素
 */
var maxSubArray = function(arr) {
    if(arr.length <= 0){
        return;
    }
    let sum = arr[0];//当前元素之前和,初始值为第一项
    let result = arr[0];//结果,初始值为第一项
    for(let i = 1; i < arr.length; i++){
        if(sum <= 0){
            sum = arr[i]; //如果当前元素之前和为负,则抛弃之前元素,当前和更新为新元素,因为负数没有增益
        } else {
            sum += arr[i];//正数时
        }
        result = Math.max(result, sum);//result取得两者最大值
    }
    return result;
};

/**
 * @param {number[]} arr
 * @return {number}
 * 功能:数组最大子序列和
 * 动态规划:dp[]连续子数组最大和
 */
var maxSubArray_1 = function(arr) {
    if(arr.length <= 0){
        return;
    }
    let dp = [];//连续子数组最大和
    dp[0] = arr[0];//
    let result = arr[0];//结果,初始值为第一项
    for(let i = 1; i < arr.length; i++){
        //连续子数组最大和,要么当前,要么之前加上当前,不会是之前,因为之前就没连续啦
        dp[i] = Math.max(dp[i - 1] + arr[i], arr[i]);
        result = Math.max(dp[i], result);
    }
    return result;
};

/**
 * @param {number[]} arr
 * @return {number}
 * 功能:数组最大子序列和
 * 动态规划:dp[]连续子数组最大和,优化空间,因为只需要记住前面一个,所以数组改为单个变量
 */
var maxSubArray_2 = function(arr) {
    if(arr.length <= 0){
        return;
    }
    let dp = arr[0];//连续子数组最大和
    let result = arr[0];//结果,初始值为第一项
    for(let i = 1; i < arr.length; i++){
        //连续子数组最大和,要么当前,要么之前加上当前,不会是之前,因为之前就没连续啦
        dp = Math.max(dp + arr[i], arr[i]);
        result = Math.max(dp, result);
    }
    return result;
};

参考:力扣

百里于2020年5月23日

如果有错,请您指出!如有侵权,请联系我删除!

你可能感兴趣的:(#,动态规划,#,贪心算法,#,力扣top)