您的当前位置:首页正文

leetCode-53: 最大子序和

2024-11-20 来源:个人技术集锦

题目描述:

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

示例:

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

解题方法1:暴力解题。双层循环,遍历数组,第一层循环就是设置开始循环的位置,第二层循环开始遍历寻找最大和。此方法时间复杂度为 O(n^2),空间复杂度 O(1)。

public static int maxSubArray1(int[] nums) {
    int sum = 0;
    // result 始终记录最大子序和
    int result = MIN_INT_VALUE;
    if (nums.length == 1) {
        return nums[0];
    }
    for (int i = 0; i < nums.length; i++) {
        sum= 0;
        for (int j = i; j < nums.length; j++) {
            sum += nums[j];
            result = sum > result ? sum : result;
        }
    }
    return result;
}

解题方法2:贪心法。遍历数组,从头开始用 sum 累加,如果 sum 一旦加上 nums[i] 变为负数,那么就舍弃 sum,从nums[i+1] 开始从 0 重新累加 sum,因为已经变为负数的 sum 只会拖累总和 result。此方法时间复杂度为 O(n),空间复杂度 O(1)。

public static int maxSubArray(int[] nums) {
    int sum = 0;
    // result 始终记录最大子序和
    int result = MIN_INT_VALUE;
    if (nums.length == 1) {
        return nums[0];
    }
    for (int i = 0; i < nums.length; i++) {
        if (sum > 0) {
            sum += nums[i];
        } else {
            sum = nums[i];
        }
        result = Math.max(result, sum);
    }
    return result;
}

j假如入参数组为:{-2, 1, -3, 4, -1, 2, 1, -5, 4},则以上两种方法得到的 result 都是 6,构成最大子序和的子序是 {4, -1, 2, 1}。

两种方法的完整代码如下所示:

package leetCode.easy.maxSubArray;

/**
 * @ClassName: MaxSubArray
 * @Author: jiaomubai
 * @Date: 2021/9/14 16:47
 * @Description: 最大子序和, LeetCode 题库第53题
 */
public class MaxSubArray {

    public static int MIN_INT_VALUE = -2147483648;

    public static int maxSubArray(int[] nums) {
        int sum = 0;
        // result 始终记录最大子序和
        int result = MIN_INT_VALUE;
        if (nums.length == 1) {
            return nums[0];
        }
        for (int i = 0; i < nums.length; i++) {
            if (sum > 0) {
                sum += nums[i];
            } else {
                sum = nums[i];
            }
            result = Math.max(result, sum);
        }
        return result;
    }

    public static int maxSubArray1(int[] nums) {
        int sum = 0;
        // result 始终记录最大子序和
        int result = MIN_INT_VALUE;
        if (nums.length == 1) {
            return nums[0];
        }
        for (int i = 0; i < nums.length; i++) {
            sum= 0;
            for (int j = i; j < nums.length; j++) {
                sum += nums[j];
                result = sum > result ? sum : result;
            }
        }
        return result;
    }

    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        int[] nums = new int[]{-2, 1, -3, 4, -1, 2, 1, -5, 4};
        int result = maxSubArray1(nums);
        System.out.println("result = " + result);
        long endTime = System.currentTimeMillis();
        System.out.println("程序运行时间:" + (endTime - startTime) + "ms");
    }

}

除此之外,此题还可使用动态规划的方法解决,后续更新...

显示全文