• 力扣第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++ 代码

    1. class Solution {
    2. public:
    3. int maxSubArray(vector<int>& nums) {
    4. // 定义最大子序和初始值为 INT_MIN,类似寻找最大最小值的题目
    5. int result = INT_MIN;
    6. int numsSize = int(nums.size());
    7. // 初始状态为数组的第一个元素
    8. int dp(nums[0]);
    9. result = dp;
    10. // 从数组的第二个元素开始遍历
    11. for (int i = 1; i < numsSize; i++) {
    12. // 状态转移方程:dp[i] = max(dp[i-1]+nums[i], nums[i])
    13. dp = max(dp + nums[i], nums[i]);
    14. // 比较当前最大子序和和dp[i]的大小,更新最大子序和
    15. result = max(result, dp);
    16. }
    17. // 返回最大子序和
    18. return result;
    19. }
    20. };

    思路和解题方法二

    首先,定义一个变量 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++ 代码

    1. class Solution {
    2. public:
    3. int maxSubArray(vector<int>& nums) {
    4. // 初始化最大子序和为数组的第一个元素
    5. int res = nums[0];
    6. // 从数组的第二个元素开始遍历
    7. for(int i = 1; i < nums.size(); i++) {
    8. // 如果前一个元素的值大于 0,说明对当前元素有增益效果
    9. if (nums[i - 1] > 0)
    10. // 将当前元素加上前一个元素的值,同时更新当前元素为以当前元素结尾的最大子序和
    11. nums[i] += nums[i - 1];
    12. // 比较当前元素和当前最大子序和的值
    13. if (nums[i] > res)
    14. // 如果当前元素大于当前最大子序和,则更新最大子序和为当前元素
    15. res = nums[i];
    16. }
    17. // 返回最终的最大子序和
    18. return res;
    19. }
    20. };

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

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

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

  • 相关阅读:
    MODBUS转PROFINET网关将电力智能监控仪表接入PROFINET网络案例
    一些杂七杂八的笔记
    Android 性能分析 之 插桩日志
    zookeeper的ZAB协议的原理以及底层源码实现超级详解
    在 Python 中检查 Argparse 的参数
    外包干了5天,技术退步明显.......
    【算法训练-回溯算法 二】【子集组合问题】子集、组合、子集II、组合总和
    python转xml为json
    T293037 [传智杯 #5 练习赛] 白色旅人
    了解一下 Fossil,一个 Git 的替代品 | Linux 中国
  • 原文地址:https://blog.csdn.net/jgk666666/article/details/133966103