【Leetcode 53】最大子序和的求解方法,直接秒懂~

本文深入探讨了最长子序和问题,通过实例讲解了如何寻找具有最大和的连续子数组。提供了两种解决方案,一种是O(N^2)的暴力解法,另一种是更高效的O(N)解法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

最长子序和:

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

我们用Leetcode中的题目为例子,URL传送-->https://leetcode-cn.com/problems/maximum-subarray/

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

解释问题

可能有些小伙伴刚入门,会有点疑惑, 什么是最长子序列呢?(大佬勿喷)

首先,我们先来理解,在这个题目中, 什么是子序列

在这个例题中,

如果我们从-2开始, 那么子序列可以为:{-2}, {-2,1},{2,-1,-3},{-2,1,-3,4}, ... , {-2,1,-3,4,-1,2,1,-5,4}

如果我们从1开始,那么子序列可以为{1},{1,-3},{1,-3,4}, ... , {1,-3,4,-1,2,1,-5,4}

如果我们从-3开始,那么子序列可以为{-3},{-3, 4}, ... , {-3,4,-1,2,1,-5,4}

 ... ...

同理, 到如果从最后一个数, 4开始,那么子序列为{4}

理解了子序列后,那么可以很直观的直到, 最长子序列和,就是我们穷举出的这么多子序列中,他们的和最大的一个子序列。

参考例子

解法一:

首先我们先用暴力的方法来破解, O(N^2)

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int length = nums.size();
        if(length == 0) return 0;
        int max = nums[0];
        int sum=0;
        for(int i=0; i<length; i++){
            sum=0;
            for(int j=i; j<length; j++){
                sum += nums[j];            //统计每个子序列的和
                if( sum > max )            //判断最大的子序列和,并保存
                    max=sum;
            }
        }


        return max;
    }
};

解法二:O(N)

由于子序列的范围为0 ~ length-1, 所以,我们可以推算出子序列的最大和也是在这个范围当中。 然后我们假设这个序列的第一个数为最大值max,此时游标i为结尾所处的子序列和为here, 然后我们从第二位开始遍历, 比较此时序列和是否大于0, 如果大于0, 则遍历的序列和与此时所处i的数组相加,如果小于等于0,那么我们将此时i处的数组的值,赋值为以i为结尾的最大的子序列和,用这样的方式遍历从1 ~ length-1,就可以找出最大子序列和, 在每次处理完子序列和的同时呢, 我们要判断当前最大的子序列,并保存下来。

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int length = nums.size();
        if(length == 0) return 0;
        int max = nums[0];
        int here = nums[0];
        
        for(int i=1; i<length; i++){
            if(here>0)
                here += nums[i];
            else
                here = nums[i];
            
            if(max<here)
                max = here;
            
        }


        return max;
    }
};

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值