深处的记忆——最大子数组和

简介: 深处的记忆——最大子数组和

题目描述

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

子数组

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


示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]

输出:6

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


思路:

题目意思很简单,最暴力的两层遍历然后取最大的那个值,能出结果,但肯定会超时。

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int f=-1e9;
        for(int i=0;i<nums.size();i++){
            int res=0;
            for(int j=i;j<nums.size();j++){
                res+=nums[j];
                f=max(f,res);
            }
        }
        return f;
    }
};

如何不超时呢,题目要求我们是不需要给出子序列的,只需要最大值即可。那么其实就到了动态规划擅长的地方了,也不需要怕动态规划,这个题还是很简单,各位读者往下看。

      很简单的道理:和负数相加总和会变小,和正数相加总和会变大


  • 定义状态:设定一个状态数组 dp,其中 dp[i] 表示以第 i 个元素结尾的最大子数组和。
  • 状态转移方程:dp[i] = max(dp[i-1] + nums[i], nums[i]),即要么将当前元素加入到之前的子数组中,要么以当前元素开始一个新的子数组。
  • 最终结果:遍历 dp 数组,找到其中的最大值,即为最大子数组和。

两种版本的代码:

class Solution {
public:
    int f[100005]; // 定义一个数组 f,用于存储以当前元素结尾的最大子数组和
    int maxSubArray(vector<int>& nums) {
        f[1] = nums[0]; // 初始化 f[1] 为第一个元素的值
        // 遍历数组 nums,计算以当前元素结尾的最大子数组和
        for(int i = 2; i <= nums.size(); i++) {
            if(f[i - 1] >= 0)
                f[i] = f[i - 1] + nums[i - 1]; // 若前一个元素结尾的子数组和大于等于 0,则将当前元素加入子数组中
            else
                f[i] = nums[i - 1]; // 否则,以当前元素开始一个新的子数组
        }
        int res = f[1]; // 初始化最大子数组和为数组第一个元素的值
        // 找到 f 数组中的最大值,即为最大子数组和
        for(int i = 2; i <= nums.size(); i++)
            res = max(res, f[i]);
        return res; // 返回最大子数组和
    }
};

简洁版本:

class Solution {
public:  
    int maxSubArray(vector<int>& nums) {
        int res = nums[0]; // 初始化最大子数组和为第一个元素的值
        for(int i = 1; i < nums.size(); i++) {
            if(nums[i - 1] >= 0) // 如果前一个元素结尾的子数组和大于等于 0
                nums[i] += nums[i - 1]; // 将当前元素加入到前一个子数组中
            if(nums[i] > res) // 如果当前子数组和大于最大值
                res = nums[i]; // 更新最大值为当前子数组和
        }
        return res; // 返回最大子数组和
    }
};
相关文章
|
8月前
|
存储
【洛谷 P1255】数楼梯 题解(递归+记忆化搜索+高精度)
这是一个使用动态规划解决的“数楼梯”问题。给定楼梯数`N`,求不同上楼方式的数量。程序通过递归函数`f()`计算,其中`f(x) = f(x - 1) + f(x - 2)`,初始条件`f(1) = 1`,`f(2) = 2`。考虑到数据规模可能很大,使用了高精度加法运算。样例输入`4`,输出`5`。代码中定义了一个存储中间结果的向量`mem`,并提供了一个用于显示高精度数的`printv()`函数。
138 0
|
8月前
|
存储
【洛谷 P2437】蜜蜂路线 题解(递归+记忆化搜索+高精度)
蜜蜂路线问题:蜜蜂从蜂房$m$到$n$($m&lt;n$)按数字递增爬行。给定$m$和$n$,求路线数。示例:$m=1$,$n=14$,输出$377$。100%数据$1\leq m,n\leq1000$。使用斐波那契序列优化,高精度处理大数。代码实现斐波那契存储并动态规划求解。
123 0
|
9月前
|
算法 测试技术 API
【线段树】1622. 奇妙序列
【线段树】1622. 奇妙序列
|
9月前
|
算法 C++
一题带你写出图论算法模板!!!
一题带你写出图论算法模板!!!
|
9月前
|
算法
【算法学习】—n皇后问题(回溯法)
【算法学习】—n皇后问题(回溯法)
|
算法
并查集模板题
并查集模板题
58 0
|
算法
数星星(树状数组模板题)
数星星(树状数组模板题)
76 0
洛谷P1443 马的遍历——广搜
洛谷P1443 马的遍历——广搜
85 0
|
机器学习/深度学习 算法
<<算法很美>>——(六)——回溯算法(下)—N皇后问题
<<算法很美>>——(六)——回溯算法(下)—N皇后问题
<<算法很美>>——(六)——回溯算法(下)—N皇后问题