LeetCode每日1题--53. 最大子数组和

92 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第33天,点击查看活动详情

前言

算法的重要性不言而喻!区分度高!

现在学习的门槛低了,只有能上网每个人都可以学编程!培训班6个月就可以培养出来能干活的人,你怎么从这些人中脱颖而出?没错!就是学算法,学一些底层和基础的东西。

说的功利点是为了竞争,卷死对手。真心话说就是能提高自己的基础能力,为技术可持续发展做好充分的准备!!!

提前入门学习书籍:CPrimerPlus、大话数据结构

image-20220705103735001

刷题网站

代码随想录 (programmercarl.com)

leetcode

我是按照代码随想录提供的刷题顺序进行刷题的,大家也可以去刷leetcode最热200道,都可以

刷题嘛,最重要的就是坚持了!!!

画图软件

OneNote

这个要经常用,遇见不懂的流程的话就拿它画一画!

笔记软件

Typoral

题目

leetcode.cn/problems/ma…

image.png

解析

这里我们很容易想到暴力解法对,就是通过两层for循环来组合并计算值的大小

一层for用来控制起始位置,一层用来组合元素,代码如下:

class Solution {
    public int maxSubArray(int[] nums) {

        int result = Integer.MIN_VALUE;

        int count = 0;
        //确认起始位置
        for(int i = 0; i< nums.length; i++){
            count = 0;
            //组合
           for(int j = i; j< nums.length; j++){
                count += nums[j];
                result =  count > result ? count : result;
            } 
        }

        return result;
    }
}

但是不幸的是这样的写法在力扣提交是过不了的,会显示超出时间限制

image.png

所以我们这里选用贪心算法试一试能不能解决,每次都选择局部最优解

局部最优:当前连续和为负数的时候立刻放弃,从下一个元素重新计算连续和,因为负数加上下一个元素下一个树只会更小!

全局最优:选取最大连续和

局部最优的情况下,并记录最大的连续和,这样的话就可以推出全局最优。

流程如图所示:

53.最大子序和.gif

完整代码

可以看出和上面的差别不大,在两层for循环的基础上做了改进!省去了很多不必要的操作

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;
    }
}

每行代码都有详细的注释,贪心算法其实就是想局部最优解,然后想办法实现,没有什么套路,就是需要多写多练!不要想着短时间内轻松的掌握它们!