【动态规划专栏】专题四:子数组问题--------最大子数组和&&环形子数组的最大和

简介: 【动态规划专栏】专题四:子数组问题--------最大子数组和&&环形子数组的最大和


题目一来源:

本题来源为:

Leetcode 53. 最大子数组和

题目1描述

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

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

算法原理

1.状态表示

经验+题目要求

对于本题而言就是:

dp[i]表示:以i位置为结尾时的所有子数组中的最大和

2.状态转移方程

分两种情况:

i位置本身自己为一个子数组

i位置与之前结合为一个子数组

因此状态方程为:

dp[i]=max(nums[i],dp[i-1]+nums[i])

3.初始化

4.填表顺序

从左往右

5.返回值

整个dp表里的最大值

代码实现

动态规划的代码基本就是固定的四步:

1.创建dp表
2.初始化
3.填表
4.返回值

本题完整代码实现:

class Solution
{
public:
    int maxSubArray(vector<int> &nums)
    {
        //创建dp表
        int n=nums.size();
        vector<int> dp(n+1);
        //初始化
        //填表
        int ret=INT_MIN;
        for(int i=1;i<=n;i++)
        {
            dp[i]=max(nums[i-1],dp[i-1]+nums[i-1]);
            ret =max(ret,dp[i]);
        }
        //返回值
        return ret;
    }
};

题目二来源

本题来源为:

Leetcode918. 环形子数组的最大和

题目二描述

给定一个长度为 n 的环形整数数组 nums ,返回 nums 的非空 子数组 的最大可能和 。

环形数组 意味着数组的末端将会与开头相连呈环状。形式上, nums[i] 的下一个元素是 nums[(i + 1) % n] , nums[i] 的前一个元素是 nums[(i - 1 + n) % n] 。

子数组 最多只能包含固定缓冲区 nums 中的每个元素一次。形式上,对于子数组 nums[i], nums[i + 1], …, nums[j] ,不存在 i <= k1, k2 <= j 其中 k1 % n == k2 % n 。

算法原理

我们可以先分析一下:

这道题在最大子数组上加了可以成环的条件。

解决这道题的关键就是可以将这道题转化成最大子数组和的问题。

子数组成环会有两种情况:

  1. 最大的子数组在中间,我们就要可以直接用最大子数组和的问题解题思路
  2. 最大子数组在首尾相连,我们可以反过来,计算中间那一部分也就是最小子数组和,最后用总和一减就是最大子数组和

1.状态表示

经验+题目要求

对于本题而言就是:

f[i]表示:以i位置为结尾时的所有子数组中的最大和

g[i]表示:以i位置为结尾时的所有子数组中的最小和

2.状态转移方程

分两种情况:

i位置本身自己为一个子数组

i位置与之前结合为一个子数组

因此状态方程为:

int x=nums[i-1];
f[i]= max(x,x+f[i -1]);
fmax = max(fmax,f[i]);
g[i]=min(x,x+ g[i-1]);
gmin = min(gmin, g[i]);
sum += X;

3.初始化

4.填表顺序

从左往右

5.返回值

代码实现

动态规划的代码基本就是固定的四步:

1.创建dp表
2.初始化
3.填表
4.返回值

本题完整代码实现:

class Solution 
{
public:
    int maxSubarraySumCircular(vector<int>& nums) 
    {
         //创建dp表
        int n=nums.size();
        vector<int> f(n+1);
        vector<int> g(n+1);
        int fmax=INT_MIN,gmin=INT_MAX,sum =0;
        //初始化
        //填表
       for(int i=1;i<=n;i++)
       {
           int x=nums[i-1];
           f[i]= max(x,x+f[i -1]);
           fmax = max(fmax,f[i]);
           g[i]=min(x,x+ g[i-1]);
           gmin = min(gmin, g[i]);
           sum += x;
       }
        //返回值
        return sum==gmin?fmax:max(fmax,sum-gmin);
    }
};
目录
打赏
0
0
1
0
8
分享
相关文章
SpringBoot实现多线程定时任务动态定时任务配置文件配置定时任务
SpringBoot实现多线程定时任务动态定时任务配置文件配置定时任务
889 0
Hologres的特性
【8月更文挑战第24天】Hologres的特性
249 3
如何随机切换代理IP以避免被封禁?
如何随机切换代理IP以避免被封禁?
313 1
杨校老师课堂之Maven下载与配置阿里云镜像
杨校老师课堂之Maven下载与配置阿里云镜像
239 0
构建一个简单的React图片画廊应用
构建一个简单的React图片画廊应用
225 0
使用Python爬取华为市场APP应用进行分析
这个网站也是作者最近接触到的一个APP应用市场类网站。讲实话,还是蛮适合新手朋友去动手学习的。毕竟爬虫领域要想进步,还是需要多实战、多分析!该网站中的一些小细节也是能够锻炼分析能力的,也有反爬虫处理。甚至是下载APP的话在Web端是无法拿到APK下载的直链,需要去APP端接口数据获取
nacos常见问题之超时异常如何解决
Nacos是阿里云开源的服务发现和配置管理平台,用于构建动态微服务应用架构;本汇总针对Nacos在实际应用中用户常遇到的问题进行了归纳和解答,旨在帮助开发者和运维人员高效解决使用Nacos时的各类疑难杂症。
1977 0
35Echarts - 柱状图(交错正负轴标签)
35Echarts - 柱状图(交错正负轴标签)
302 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问