【LeetCode】53. 最大子序和|Java 刷题打卡

483 阅读2分钟

本文正在参加「Java主题月 - Java 刷题打卡」,详情查看 活动链接

题目描述

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

示例 1:

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

示例 2:

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

示例 3:

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

示例 4:

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

示例 5:

输入:nums = [-100000]
输出:-100000

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/ma… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路分析

暴力解法,首先确定所有的子数组,子数组有开始下标和结束下标,使用双层循环,外层循环i控制子数组的起始位置,内层循环j控制子数组的结束位置,获取所有子数组的和,并取最大值即可。

最大子序和.png

代码展示

public int maxSubArray(int[] nums) {
    int length = nums.length;
    // 当数组长度为1时,最大值就是第一个值
    if (length == 1)
        return nums[0];
    // 最大值,默认设置为第一个值
    int maxV = nums[0];
    // 双层循环,外层循环控制子数组的起始位置,内层循环控制子数组的结束位置
    // 每次获取到值都与当前最大值比较,并更新最大值
    // 时间复杂度O(n),空间复杂度O(1)
    for (int i = 0; i < length; i++) {
        if (nums[i] > maxV)
            maxV = nums[i];
        int total = nums[i];
        for (int j = i + 1; j < length; j++) {
            total += nums[j];
            if (total > maxV)
                maxV = total;
        }
    }
    return maxV;
}

总结

坚持!!!

官方题解

/**
 * 动态规划
 * 最大子数组的确定:nums[i]是单独成为最大子数组还是加入前方的子数组,取决于nums[i]与f(i-1)+nums[i]
 */
public static int maxSubArrayOfficial(int[] nums) {
    int pre = 0, maxAns = nums[0];
    for (int x : nums) {
        pre = Math.max(pre + x, x);
        maxAns = Math.max(maxAns, pre);
    }
    return maxAns;
}