⭐算法入门⭐《动态规划 - 线性DP》简单02 —— LeetCode 53. 最大子序和

本文详细介绍了如何解决LeetCode上的53题——最大子序和,通过C语言讲解动态规划思路,提供基础框架代码,并分析时间复杂度。解题报告中阐述了状态转移方程,以及代码实现过程,帮助读者理解并掌握连续子数组问题的解决技巧。
摘要由CSDN通过智能技术生成

🙉饭不食,水不饮,题必须刷🙉

C语言免费动漫教程,和我一起打卡!
🌞《光天化日学C语言》🌞

LeetCode 太难?先看简单题!
🧡《C语言入门100例》🧡

数据结构难?不存在的!
🌳《数据结构入门》🌳

LeetCode 太简单?算法学起来!
🌌《夜深人静写算法》🌌

一、题目

1、题目描述

  给定一个整数数组 n u m s nums nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
  样例输入: n u m s = [ − 2 , 1 , − 3 , 4 , − 1 , 2 , 1 , − 5 , − 7 ] nums = [-2,1,-3,4,-1,2,1,-5,-7] nums=[2,1,3,4,1,2,1,5,7]
  样例输出: 6 6 6, 即 [ 4 , − 1 , 2 , 1 ] [4,-1,2,1] [4,1,2,1]

2、基础框架

  • c++ 版本给出的基础框架代码如下:
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
    }
};

3、原题链接

LeetCode 53. 最大子序和

二、解题报告

1、思路分析

由于要求的是连续的子数组,所以对于第 i i i 个元素,状态转移一定是从 i − 1 i-1 i1 个元素转移过来的。

  • 基于这一点,可以令 f [ i ] f[i] f[i] 表示以 i i i 号元素结尾的最大值。
  • 那么很自然,这个最大值必然包含 n u m s [ i ] nums[i] nums[i] 这个元素,那么要不要包含 n u m s [ i − 1 ] , n u m s [ i − 2 ] , n u m s [ i − 3 ] , . . . , n u m s [ k ] nums[i-1],nums[i-2],nums[i-3],...,nums[k] nums[i1],nums[i2],nums[i3],...,nums[k] 呢?其实就是看第 i − 1 i-1 i1 号元素结尾的最大值是否大于零,也就是: f [ i − 1 ] ≤ 0 f[i-1] \le 0 f[i1]0 时,则 前 i − 1 i-1 i1 个元素是没必要包含进来的。所以就有状态转移方程:
  • f [ i ] = { n u m s [ 0 ] i = 0 n u m s [ i ] f [ i − 1 ] ≤ 0 n u m s [ i ] + f [ i − 1 ] f [ i − 1 ] > 0 f[i] = \begin{cases} nums[0] & i = 0 \\ nums[i] & f[i-1] \le 0 \\ nums[i] + f[i-1] & f[i-1] > 0\end{cases} f[i]=nums[0]nums[i]nums[i]+f[i1]i=0f[i1]0f[i1]>0
  • 一层循环枚举后,取 m a x ( f [ i ] ) max(f[i]) max(f[i]) 就是答案了。

2、时间复杂度

  • 状态数: O ( n ) O(n) O(n)
  • 状态转移: O ( 1 ) O(1) O(1)
  • 时间复杂度: O ( n ) O(n) O(n)

3、代码详解

class Solution {
    int f[30010];
public:
    int maxSubArray(vector<int>& nums) {
        int maxValue = nums[0];
        f[0] = nums[0];                          // (1)
        for(int i = 1; i < nums.size(); ++i) {
            f[i] = nums[i];
            if(f[i-1] > 0) {
                f[i] += f[i-1];                  // (2)
            }
            maxValue = max(maxValue, f[i]);      // (3)
        }
        return maxValue;
    }
};
  • ( 1 ) (1) (1) 初始值;
  • ( 2 ) (2) (2) 状态转移;
  • ( 3 ) (3) (3) 过程中取最大值;

三、本题小知识

连续子数组问题,可以考虑前一个元素已经计算出来的状态进行下一个元素的求解。


评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

英雄哪里出来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值