首页 > 其他分享 >leetcode 53. 最大子数组和

leetcode 53. 最大子数组和

时间:2024-11-26 16:57:08浏览次数:9  
标签:nums int sum mid 53 数组 leetcode dp left

53. 最大子数组和

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

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

 

法一

1.假如全是负数,那就是找最大值即可,因为负数肯定越加越大。

2.如果有正数,则肯定从正数开始计算和,不然前面有负值,和肯定变小了,所以从正数开始。

3.当和小于零时,这个区间就告一段落了,然后从下一个正数重新开始计算(也就是又回到 2 了)。而 dp 也就体现在这个地方。

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int maxSum = nums[0];
        int sum = 0,size = nums.size(); //当前最大连续子序列和为sum
        for(int i = 0;i < size;i++){
            if(sum > 0)  sum += nums[i];//如果sum>0,则说明sum对结果有增益效果,则sum保留并加上当前遍历数字
            else  sum = nums[i];//如果sum<=0,则说明sum对结果无增益效果,需要舍弃,则sum直接更新为当前遍历数字
            maxSum = max(maxSum , sum);//如果这一轮循环的nums[i]是负数,sum就可能变小了,所以需要和maxSum比大小
        }
        return maxSum;
    }
};

法二

使用额外空间

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int maxRes = nums[0],size = nums.size();
        int dp[size];//dp[i]代表以第 i 个数结尾的「连续子数组的最大和」
        dp[0] = nums[0];
        for(int i = 1; i < size; i++){
            //不是dp[i]=max(dp[i-1],dp[i-1]+nums[i]);而是dp[i]=max(nums[i],dp[i-1]+nums[i]);
            dp[i] = max(nums[i], dp[i-1] + nums[i]);
            maxRes = max(maxRes, dp[i]);
        }
        return maxRes;
    }
};

法三:递归分治法

class Solution {
public:
    int max3(int num1,int num2,int num3){
        return max(num1,max(num2,num3));
    }

    int maxCrossingSum(vector<int>& nums, int left, int mid, int right){
        //考虑第 3 部分跨越两个区间的连续子数组的时候,由于 nums[mid] 与 nums[mid + 1] 一定会被选取
        //可以从中间向两边扩散,扩散到底选出最大值
        int sum = 0;
        int leftSum = INT_MIN;
        // 左半边包含 nums[mid] 元素,最多可以到什么地方
        // 走到最边界,看看最值是什么
        // 计算以 mid 结尾的最大的子数组的和
        for(int i = mid;i >= left;i--){
            sum += nums[i];
            if(sum > leftSum)  leftSum = sum;
        }
        sum = 0;
        int rightSum = INT_MIN;
        // 右半边不包含 nums[mid] 元素,最多可以到什么地方
        // 计算以 mid+1 开始的最大的子数组的和
        for (int i = mid + 1; i <= right; i++) {
            sum += nums[i];
            if (sum > rightSum)  rightSum = sum;          
        }
        return leftSum + rightSum;
    }

    int maxSubArraySum(vector<int>& nums,int left,int right){
        if(left == right)  return nums[left];
        int mid = left + (right - left) / 2;//可以很好地防止溢出
        //连续子序列的最大和主要由这三部分子区间里元素的最大和得到:
        //第 1 部分:子区间 [left, mid];
        //第 2 部分:子区间 [mid + 1, right];
        //第 3 部分:包含子区间 [mid , mid + 1] 的子区间,即 nums[mid] 与 nums[mid + 1] 一定会被选取。
        //对这三个部分求最大值即可。
        return max3(maxSubArraySum(nums, left, mid), maxSubArraySum(nums, mid+1, right), maxCrossingSum(nums, left, mid, right));
    }

    int maxSubArray(vector<int>& nums) {
        return maxSubArraySum(nums,0,nums.size()-1);
    }
};

 

标签:nums,int,sum,mid,53,数组,leetcode,dp,left
From: https://www.cnblogs.com/uacs2024/p/18570497

相关文章

  • leetcode78 子集
    leetcode78子集思路:深度优先搜索回溯分析此类问题可以先用树形结构模拟代码逻辑。那么根据这个解答树,首先我们的回溯搜索函数应该由这么几部分组成将搜索获得的答案加入到res中。for循环遍历搜索下一个元素(比如在初始列表为空的时候,第一位可以选1,2,3显然需要通过循环实现)......
  • 对数组操作的相关js函数
    汇总一下js中,数组的相关函数(如有问题,请在评论区q我哦!感谢!)1.添加和删除数组元素//1.push在数组末尾添加一个或多个元素,并返回新的长度(改变原数组)letarray=[1,2,3];array.push(4);console.log(array);//输出[1,2,3,4]//2.pop移除数组末尾的一个元素,并返......
  • 代码随想录算法训练营第十一天(LeetCode150.逆波兰表达式求值;LeetCode239.滑动窗口最大
    LeetCode150.逆波兰表达式求值题目链接:逆波兰表达式求值题目链接思路主要是要理解逆波兰表达式的定义,在理解了逆波兰表达式的定义后,使用栈就可以直接做了。逆波兰表达式是一种后缀表达式,所谓后缀就是指运算符写在后面。平常使用的算式则是一种中缀表达式,如(1+2)......
  • 代码随想录算法训练营第十天(LeetCode232.用栈实现队列;LeetCode225.用队列实现栈;LeetCo
    LeetCode232.用栈实现队列题目链接:用栈实现队列题目链接思路队列是先进先出,栈是先进后出,为了能够让栈可以模拟队列的先进先出,我们设置两个栈,一个栈作为入栈,一个栈作为出栈,我们在入栈存储完数据后,将入栈中的数据全部存储到出栈中,那么从出栈中弹出来的数据就是先进先出的......
  • 「Luogu P3953」[NOIP2017 提高组] 逛公园
    题目策策同学特别喜欢逛公园。公园可以看成一张\(N\)个点\(M\)条边构成的有向图,且没有自环和重边。其中\(1\)号点是公园的入口,\(N\)号点是公园的出口,每条边有一个非负权值,代表策策经过这条边所要花的时间。策策每天都会去逛公园,他总是从\(1\)号点进去,从\(N\)号点......
  • 一维数组的定义
    数组的定义定义格式如下:类型名 数组名 [常量表达式];例如:inta[10];Copy说明:类型名是指数组元素的类型,它可以是任何类型,同一个数组中的元素具有相同类型。因此我们可以说,数组是由固定数量的相同类型的元素组成。上面例子中int说明这个数组的类型是整数类型。数组......
  • SpringBoot云笔记设计00530 程序+源码+数据库+调试部署+开发环境
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表系统内容:用户,文件类型,笔记类型,文件信息,日常笔记开题报告内容题目:基于SpringBoot的云笔记系统设计一、研究背景与意义随着信息技术的飞速发展,个人及企业......
  • CF1753C题解
    鲜花被卡了一万年。考虑过序列变换的各种情况和逆序对,结果这俩情况状态太多,而且相同逆序对ans也不一定相同。/llsol我们最后想要的状态为所有\(0\)都在\(1\)的左边,令\(cnt_0\)为\(0\)的个数,\(cnt_1\)为\(1\)个数。\(cnt_0+cnt_1=n\),结束的状态前\(cnt_0\)个数......
  • GaussDB SQL基础语法示例-数组表达式
    一、前言SQL是用于访问和处理数据库的标准计算机语言。GaussDB支持SQL标准(默认支持SQL2、SQL3和SQL4的主要特性)。本系列将以《云数据库GaussDB—SQL参考》在线文档为主线进行介绍。欢迎使用GaussDB数据库数组表达式。在本文中,我们将介绍GaussDB数据库中数组表达式的概念、语法......
  • LeetCode题练习与总结:数组中两个数的最大异或值--421
    一、题目描述给你一个整数数组 nums ,返回 nums[i]XORnums[j] 的最大运算结果,其中 0≤i≤j<n 。示例1:输入:nums=[3,10,5,25,2,8]输出:28解释:最大运算结果是5XOR25=28.示例2:输入:nums=[14,70,53,83,49,91,36,80,92,51,66,70]输出:127提示:1<=......