贪心——53. 最大子数组和

简介: 本专栏按照数组—链表—哈希—字符串—栈与队列—二叉树—回溯—贪心—动态规划—单调栈的顺序刷题,采用代码随想录所给的刷题顺序,一个正确的刷题顺序对算法学习是非常重要的,希望对大家有帮助

1 题目描述

  1. 最大子数组和

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

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

2 题目示例

示例 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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/maximum-subarray

3 题目提示

1 <= nums.length <= 10^5^
-10^4^ <= nums[i] <= 10^4^

4 思路

贪心贪的是哪里呢?
如果-2 1在一起,计算起点的时候,一定是从1开始计算,因为负数只会拉低总和,这就是贪心贪的地方!
局部最优:当前“连续和"为负数的时候立刻放弃,从下一个元素重新计算"连续和",因为负数加上下一个元素“连续和"只会越来越小。
全局最优:选取最大"连续和”
局部最优的情况下,并记录最大的“连续和”,可以推出全局最优。
从代码角度上来讲:遍历nums,从头开始用count累积,如果count一旦加上nums[i]变为负数,那么就应该从nums[i+1]开始从0累积count了,因为已经变为负数的count,只会拖累总和。
这相当于是暴力解法中的不断调整最大子序和区间的起始位置。
那有同学问了,区间终止位置不用调整么?如何才能得到最大"连续和"呢?
区间的终止位置,其实就是如果count取到最大值了,及时记录下来了。例如如下代码:

if (count > result) result = count;

这样相当于是用result记录最大子序和区间和(变相的算是调整了终止位置)。
image.png

红色的起始位置就是贪心每次取count为正数的时候,开始一个区间的统计。

时间复杂度:O(n)·空间复杂度:O(1)
当然题目没有说如果数组为空,应该返回什么,所以数组为空的话返回啥都可以了。
不少同学认为如果输入用例都是-1,或者都是负数,这个贪心算法跑出来的结果是0,这是又一次证明脑洞模拟不靠谱的经典案例,建议大家把代码运行一下试一试,就知道了,也会理解为什么result 要初始化为最小负数了。

5 我的答案

class Solution {
    public int maxSubArray(int[] nums) {
        if (nums.length == 1){
            return nums[0];
        }
        int sum = Integer.MIN_VALUE;
        int count = 0;
        for (int i = 0; i < nums.length; i++){
            count += nums[i];
            sum = Math.max(sum, count); // 取区间累计的最大值(相当于不断确定最大子序终止位置)
            if (count <= 0){
                count = 0; // 相当于重置最大子序起始位置,因为遇到负数一定是拉低总和
            }
        }
       return sum;
    }
}
相关文章
|
2月前
|
消息中间件 Kubernetes NoSQL
动态规划-状态压缩、树形DP问题总结
动态规划-状态压缩、树形DP问题总结
|
9月前
|
算法
【学会动态规划】最大子数组和(19)
【学会动态规划】最大子数组和(19)
28 0
|
9月前
|
算法
【学会动态规划】最小路径和(9)
【学会动态规划】最小路径和(9)
27 0
|
10月前
|
测试技术
【动态规划刷题 10】最大子数组和 III && 环形子数组的最大和
【动态规划刷题 10】最大子数组和 III && 环形子数组的最大和
|
10月前
|
机器学习/深度学习 算法
【动态规划刷题 9】最大子数组和 III && 环形子数组的最大和
【动态规划刷题 9】最大子数组和 III && 环形子数组的最大和
|
2月前
|
算法 C++
C++019-C++暴力枚举
C++019-C++暴力枚举
C++019-C++暴力枚举
|
人工智能 算法 搜索推荐
LeetCode 周赛 338,贪心 / 埃氏筛 / 欧氏线性筛 / 前缀和 / 二分查找 / 拓扑排序
大家好,我是小彭。 上周末是 LeetCode 第 338 场周赛,你参加了吗?这场周赛覆盖的知识点很多,第四题称得上是近期几场周赛的天花板。
89 0
|
算法 Java 测试技术
【LeetCode】 53. 最大子序和(贪心算法)
53. 最大子序和(贪心算法)
71 0
|
算法 Java Python
【LeetCode】 53. 最大子序和(动态规划)
53. 最大子序和(动态规划)
80 0
【LeetCode】 53. 最大子序和(动态规划)