力扣第53题 最大子树组和 动态规划 + 贪心 两种方法 c++

题目

53. 最大子数组和

中等

相关标签

数组 分治 动态规划

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

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

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

提示:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104

进阶: 如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。

思路和解题方法一

首先,定义一个变量 result 来保存当前的最大子序和,初始值设置为 INT_MIN,表示理论上的最小值。

然后,定义一个变量 dp 来表示以当前元素结尾的最大子序和。将 dp 的初始值设置为第一个元素 nums[0]。

接下来,从数组的第二个元素开始遍历,对于每个元素 nums[i],进行以下操作:

  1. 比较 dp + nums[i] 和 nums[i] 的大小,取其中较大的值作为以当前元素结尾的最大子序和。这里使用 max() 函数进行比较。

  2. 将 result 更新为 result 和 dp 的较大值,保持 result 始终记录着最大的子序和。

最后,返回 result。

复杂度

时间复杂度:

O()

  • 时间复杂度:O(n),其中 n 是数组的长度。同样需要遍历整个数组一次。

空间复杂度

O()

  • 空间复杂度:O(1),同样只需要常数级别的额外空间用于存储变量。

c++ 代码

cpp 复制代码
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        // 定义最大子序和初始值为 INT_MIN,类似寻找最大最小值的题目
        int result = INT_MIN;
        int numsSize = int(nums.size());
        
        // 初始状态为数组的第一个元素
        int dp(nums[0]);
        result = dp;
        
        // 从数组的第二个元素开始遍历
        for (int i = 1; i < numsSize; i++) {
            // 状态转移方程:dp[i] = max(dp[i-1]+nums[i], nums[i])
            dp = max(dp + nums[i], nums[i]);
            
            // 比较当前最大子序和和dp[i]的大小,更新最大子序和
            result = max(result, dp);
        }
        // 返回最大子序和
        return result;
    }
};

思路和解题方法二

首先,定义一个变量 res 来保存当前的最大子序和,初始值设置为数组的第一个元素 nums[0]

然后,从数组的第二个元素开始遍历,对于每个元素 nums[i],我们进行以下操作:

  1. 如果前一个元素 nums[i-1] 的值大于 0,说明以 nums[i-1] 结尾的子序和对于计算当前的最大子序和有正向增益效果,因此将 nums[i] 加上 nums[i-1],即 nums[i] += nums[i-1]
  2. 比较当前的 nums[i]res 的值,如果 nums[i] 大于 res,则更新 res 的值为 nums[i]

通过遍历整个数组,不断更新 res 的值,最终可以得到数组中的最大子序和。

这种解法利用了动态规划的思想,在遍历过程中不断更新当前的状态,以求得最优解。

复杂度

时间复杂度:

O()

  • 时间复杂度:O(n),其中 n 是数组的长度。同样需要遍历整个数组一次。

空间复杂度

O()

  • 空间复杂度:O(1),同样只需要常数级别的额外空间用于存储变量。

c++ 代码

cpp 复制代码
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        // 初始化最大子序和为数组的第一个元素
        int res = nums[0];
        
        // 从数组的第二个元素开始遍历
        for(int i = 1; i < nums.size(); i++) {
            // 如果前一个元素的值大于 0,说明对当前元素有增益效果
            if (nums[i - 1] > 0)
                // 将当前元素加上前一个元素的值,同时更新当前元素为以当前元素结尾的最大子序和
                nums[i] += nums[i - 1];
            
            // 比较当前元素和当前最大子序和的值
            if (nums[i] > res)
                // 如果当前元素大于当前最大子序和,则更新最大子序和为当前元素
                res = nums[i];
        }
        
        // 返回最终的最大子序和
        return res;  
    }
};

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦 >人< 。

相关推荐
zore_c6 分钟前
【数据结构】队列——超详解!!!(包含队列的实现)
c语言·网络·数据结构·c++·笔记·算法·链表
雾岛听蓝6 分钟前
C++ 模板初阶
开发语言·c++
小杰帅气7 分钟前
智能指针喵喵喵
开发语言·c++·算法
特立独行的猫a8 分钟前
cpp-linenoise介绍——让命令行拥有猫一般的敏捷
c++·ui·命令行·cpp-linenoise
智驱力人工智能16 分钟前
守护生命的水上之眼 无人机人员落水检测系统的技术攻坚与应用实践 无人机溺水识别 山区水库无人机落水检测系统 水域安全无人机部署指南
大数据·人工智能·算法·安全·无人机·边缘计算
hweiyu0018 分钟前
排序算法选型决策树
算法·排序算法
蓝色汪洋2 小时前
xtu oj矩阵
算法
hh随便起个名8 小时前
力扣二叉树的三种遍历
javascript·数据结构·算法·leetcode
橘子真甜~8 小时前
C/C++ Linux网络编程15 - 网络层IP协议
linux·网络·c++·网络协议·tcp/ip·计算机网络·网络层
Dingdangcat8610 小时前
城市交通多目标检测系统:YOLO11-MAN-FasterCGLU算法优化与实战应用_3
算法·目标检测·目标跟踪