【OJ】动归练习五之子组串

个人主页 : zxctscl
如有转载请先通知

题目

  • 1. 53. 最大子数组和
    • 1.1 分析
    • 1.2 代码
  • 2. 918. 环形子数组的最大和
    • 2.1 分析
    • 2.2 代码
  • 3. 152. 乘积最大子数组
    • 3.1 分析
    • 3.2 代码
  • 4. 1567. 乘积为正数的最长子数组长度
    • 4.1 分析
    • 4.2 代码

1. 53. 最大子数组和

在这里插入图片描述

1.1 分析

一、题目解析:
求子数组最大和,可能会有所有元素和和子数组所有的和比较,然后取最大的一个。

二、算法原理:

  1. 状态表示
    以i位置为结尾,来求子数组最大和。
    dp[i]:表示以i位置为结尾所有字数组中的最大和

  2. 状态转移方程
    那么dp[i]就可能分两种情况:一种就是只有一个数,就是i对应的nums[i];另一种情况就是不止一个数就是i-1最大的子数组和dp[i-1]加上i位置对应的nums[i]。然后取这两种情况的最大值。
    状态转移方程:dp[i]=max(nums[i],dp[i-1]+nums[i])

  3. 初始化
    第一位置的值可能也会取到,那么就多开一个空间,把dp[0]位置初始化为0,从而不影响后面的最大和。这里同时也要注意下标的映射关系,多开了一个空间,那么对应nums[i]的位置就得向前挪一个。

  4. 填表顺序
    从左往右

  5. 返回值
    就返回dp表中最大的值。
    为了方便,先记录一下当前位置最大子序列和最大值,然后更新。
    在这里插入图片描述

1.2 代码

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int n=nums.size();
        vector<int> dp(n+1);
        dp[0]=0;
         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;

    }
};

2. 918. 环形子数组的最大和

在这里插入图片描述

2.1 分析

一、题目解析:
这个题与上面一个类似,就是变成了环形。那么这里就可以分为两类:一类是中间相连子数组求最大和;另一类是在结尾和开头求最大和,这里会不方便计算,那么就过来,求中间连续子数组最小和,然后用这个数组的和减去这个最小和,就是这段首尾的最大和。然后比较这两类的和大小,返回最大的那个值就可以了。
在这里插入图片描述

二、算法原理:

  1. 状态表示
    以i位置为结尾,分两种情况:一种来求子数组最大和,一种求最小和
    f[i]:表示以i位置为结尾所有字数组中的最大和
    g[i]:表示以i位置为结尾所有字数组中的最小和

  2. 状态转移方程
    那么f[i]就可能分两种情况:一种就是只有一个数,就是i对应的nums[i];另一种情况就是不止一个数就是i-1最大的子数组和f[i-1]加上i位置对应的nums[i]。然后取这两种情况的最大值。
    f[i]:状态转移方程:f[i]=max(nums[i],f[i-1]+nums[i])

那么g[i]也可能分两种情况:一种就是只有一个数,就是i对应的nums[i];另一种情况就是不止一个数就是i-1最小的子数组和g[i-1]加上i位置对应的nums[i]。然后取这两种情况的最小值。
f[i]:状态转移方程:g[i]=min(nums[i],g[i-1]+nums[i])

  1. 初始化
    第一位置的值可能也会取到,那么就多开一个空间,把f[0]位置和g[0]初始化为0,从而不影响后面的最大和。这里同时也要注意下标的映射关系,多开了一个空间,那么对应nums[i]的位置就得向前挪一个。

  2. 填表顺序
    从左往右

  3. 返回值
    一类是在f表中找到最大值fmax
    一类是在g表中找到最小值gmin
    但是在g表中可能会存在全是负数序列的情况,这里就得加一个判断,如果sum=gmin,那么就返回fmax,不然就比较两类和的大小,返回大的那一个。
    在这里插入图片描述

2.2 代码

class Solution {
public:
    int maxSubarraySumCircular(vector<int>& nums) {
       int n = nums.size();
       vector<int> f(n+1),g(n+1);
     
       int fmax=INT_MIN,sum=0,gmin=INT_MAX;

        for(int i=1;i<=n;i++)
        {
            f[i]=max(nums[i-1],f[i-1]+nums[i-1]);
            fmax=max(fmax,f[i]);
 
            g[i]=min(nums[i-1],g[i-1]+nums[i-1]);
            gmin=min(gmin,g[i]);
            sum+=nums[i-1];
        }
       return sum==gmin?fmax:max(fmax,sum-gmin);
    }
};

3. 152. 乘积最大子数组

在这里插入图片描述

3.1 分析

一、题目解析:
求子数组最大乘积,可能会有所有元素和和子数组所有的和比较,然后取最大的一个。但是可能会存在i位置小于0,所以的多加一个数组。

二、算法原理:

  1. 状态表示
    以i位置为结尾,来求子数组乘积。
    f[i]:表示以i位置为结尾所有字数组中的最大乘积
    g[i]:表示以i位置为结尾所有字数组中的最小乘积
  2. 状态转移方程
    那么f[i]就可能分两种情况:一种就是只有一个数,就是i对应的nums[i];另一种情况就是不止一个数就是i-1最大的子数组乘积f[i-1]乘i位置对应的nums[i],但是这里的nums[i]可能是小于0,所以这里还得分两种情况:一个是nums[i]>0,那么就是最大的子数组乘积f[i-1]乘i位置对应的nums[i];如果nums[i]<0,就是最小的子数组乘积g[i-1]乘i位置对应的nums[i]。然后取这两种情况的最大值。
    在这里插入图片描述

g[i]就可能分两种情况:一种就是只有一个数,就是i对应的nums[i];另一种情况就是不止一个数就是i-1最小的子数组乘积f[i-1]乘i位置对应的nums[i],但是这里的nums[i]可能是小于0,所以这里还得分两种情况:一个是nums[i]>0,那么就是最小的子数组乘积g[i-1]乘i位置对应的nums[i];如果nums[i]<0,就是最大的子数组乘积g[i-1]乘i位置对应的nums[i]。然后取这两种情况的最小值。
在这里插入图片描述

  1. 初始化
    第一位置的值可能也会取到,那么就多开一个空间,把f[0]位置和g[0]初始化为1,从而不影响后面的最大乘积。这里同时也要注意下标的映射关系,多开了一个空间,那么对应nums[i]的位置就得向前挪一个。

  2. 填表顺序
    从左往右
    两个表一起填

  3. 返回值
    f表里面的最大值
    在这里插入图片描述

3.2 代码

class Solution {
public:
    int maxProduct(vector<int>& nums) {
      int n = nums.size();
       vector<int> f(n+1),g(n+1);
       f[0]=g[0]=1;
       int ret=INT_MIN;

        for(int i=1;i<=n;i++)
        {
            int x=nums[i-1],y=f[i-1]*nums[i-1],z=g[i-1]*nums[i-1];
            f[i]=max(x,max(y,z));
            g[i]=min(x,min(y,z));
        
            ret=max(ret,f[i]);
        }
        return ret;
    }
};

4. 1567. 乘积为正数的最长子数组长度

在这里插入图片描述

4.1 分析

一、题目解析:
求数组乘积为正数的最长长度,可能会有所有元素和和子数组所有的和比较,然后取最大的一个。但是可能会存在i位置小于0,所以的多加一个数组。
二、算法原理:

  1. 状态表示
    以i位置为结尾,所有子数组乘积为正数的最长长度。
    f[i]:表示以i位置为结尾所有字数组中乘积为正数的最长长度
    g[i]:表示以i位置为结尾所有字数组中乘积为负数的最长长度

  2. 状态转移方程
    那么f[i]就可能分两种情况:一种就是只有一个数,就是i对应的nums[i],如果num[i]<0,长度就为0,num[i]>0,长度就为1;
    另一种情况就是不止一个数就是i-1最大的子数组乘积为正数的最长长度,如果num[i]>0,长度就为就是以i-1为结尾的子数组乘积为正数的最长长度再加1;num[i]<0,长度就为就是以i-1为结尾的子数组乘积为负数的最长长度再加1,但是如果前面g[i-1]的结果为0,那么结果就是0,所以得先判断g[i-1]是否等于0。
    在这里插入图片描述
    再把这两种情况优化一下,当num[i]>0,那么如果只有num[i]结果就是1,也就是没有不止一个元素的时候大,所以,直接用f[i-1]+1就行。
    num[i]<0,先判断判断g[i-1]是否等于0,是就是0,不是就取g[i-1]+1。
    f的状态转移方程:
    在这里插入图片描述

那么g[i]就可能分两种情况:一种就是只有一个数,就是i对应的nums[i],如果num[i]<0,长度就为1,num[i]>0,长度就为0;
另一种情况就是不止一个数就是i-1最大的子数组乘积为负数的最长长度,如果num[i]>0,长度就为就是以i-1为结尾的子数组乘积为负数的最长长度再加1,也不能直接加一,先判断判断g[i-1]是否等于0,是就是0,不是就取g[i-1]+1;
num[i]<0,长度就为就是以i-1为结尾的子数组乘积为正数的最长长度再加1。
在这里插入图片描述
g的状态转移方程:
在这里插入图片描述

  1. 初始化
    第一位置的值可能也会取到,那么就多开一个空间,把f[0]位置初始化为0,g[0]初始化,0,从而不影响后面的结果。这里同时也要注意下标的映射关系,多开了一个空间,那么对应nums[i]的位置就得向前挪一个。

  2. 填表顺序
    从左往右
    两个表一起填

  3. 返回值
    返回f表里面最大值
    在这里插入图片描述

4.2 代码

class Solution {
public:
    int getMaxLen(vector<int>& nums) {
       int n = nums.size();
       vector<int> f(n+1),g(n+1);
       int ret=INT_MIN;
        for(int i=1;i<=n;i++)
        {
            if(nums[i-1]>0)
            {
                f[i]=f[i-1]+1;
                g[i]=g[i-1]==0?0:g[i-1]+1;

            }
            else if(nums[i-1]<0)
            {
                f[i]=g[i-1]==0?0:g[i-1]+1;
                 g[i]=f[i-1]+1;
            }
            ret=max(ret,f[i]);
        
           
        }
        return ret;
    }
};

有问题请指出,大家有一起进步!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/501520.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解锁网络新境界:国内IP地址好用的有哪些?

在互联网的世界里&#xff0c;IP地址是每一个网络设备的“身份证”&#xff0c;是实现网络通信的关键。在国内&#xff0c;随着网络技术的不断发展和普及&#xff0c;IP地址的使用和管理也日益受到关注。虎观代理将深入解析国内IP地址的选择与使用&#xff0c;为大家推荐一些好…

爬取b站音频和视频数据,未合成一个视频

一、首先找到含有音频和视频的url地址 打开一个视频&#xff0c;刷新后&#xff0c;找到这个包&#xff0c;里面有我们所需要的数据 访问这个数据包后&#xff0c;获取字符串数据&#xff0c;用正则提取&#xff0c;再转为json字符串方便提取。 二、获得标题和音频数据后&…

XXII Open Cup, Grand Prix of Daejeon C. AND PLUS OR(思维 结论)

题目 给定n(n<20)&#xff0c;再输入2^n个数&#xff0c;分别代表a[0]到a[2^n-1]&#xff0c;第i个数ai(0<ai<1e7) 问是否存在一对下标i、j满足a[i]a[j]<a[i&j]a[i|j] 如果不存在&#xff0c;输出-1&#xff0c;否则输出任意一对(i,j)即可 思路来源 官方题…

Https【Linux网络编程】

目录 一、为什么需要https 二、常见加密方法 1、对称加密 2、非对称加密 3、数据指纹 三、选择什么加密方案&#xff1f; 方案一&#xff1a;对称加密&#xff08;&#xff09; 方案二&#xff1a;双方使用非对称加密&#xff08;效率低&#xff09; 方案三&#xff1a…

电子级高纯PFA材质实验室器皿耗材PFA漏斗PFA试剂瓶PFA烧杯

PFA三角漏斗&#xff0c;整体均是PFA材质&#xff0c;无污染风险&#xff0c;可高压灭菌。 尺寸&#xff1a;外径40mm、160mm PFA三角漏斗 特点&#xff1a; 1、一体式成型&#xff0c;结构稳定&#xff1b; 2、化学耐受性强&#xff0c;耐受强酸、强碱以及各种有机溶剂&…

C语言例3-1:阅读下列程序,写出程序运行的结果。

代码如下&#xff1a; #include <stdio.h> int main(void) {int x8;do{printf("*");x--;x--;}while(x0);printf("\n");return 0; } 结果如下&#xff1a; 分析&#xff1a; do-while语句&#xff0c;先执行后判断先打印 "*" &#xff0…

58集团校园招聘(含内推码)

招聘链接&#xff1a;校招链接 内推码在后文。 内推码 填写我的推荐码&#xff1a;EVBAJS 投递

1、Cocos Creator 基础入门

目录 Cocos Creator 是什么&#xff1f; 语言支持 功能特性 工作流程 功能模块 相关游戏 参考 Cocos Creator 是什么&#xff1f; Cocos Creator 既是一款高效、轻量、免费开源的跨平台 2D&3D 图形引擎&#xff0c;也是一个实时 2D&3D 数字内容创作平台。拥有…

线上剧本杀小程序成为行业发展大势,商家该如何选择?

在过去的几年中&#xff0c;剧本杀成为了年轻人娱乐社交的新方式&#xff0c;深受年轻人的喜欢&#xff0c;市场规模持续上升。 目前&#xff0c;剧本杀的布局也向线上发展&#xff0c;线上剧本杀的发展势头持续上升&#xff0c;规模也在持续扩大中。通过开发剧本杀小程序&…

在Windows的Docker上部署Mysql服务

在我们做一些和数据库相关的测试时&#xff0c;往往需要快速部署一个数据库作为数据源。如果开发环境是Windows&#xff0c;且开发的代码不依赖于系统&#xff0c;即不用在linux上做开发&#xff0c;则可以将全套环境都部署在Windows上。 本地安装数据库会污染操作系统环境&…

某某45浏览器干净卸载详细教程

​ 某某45是个什么软件&#xff1f;某某45浏览器是病毒吗&#xff1f;这个问题想必困惑着很多小伙伴&#xff0c;新装机的电脑总是有某某45全家桶。那么今天咱们一起看看。 ​ 某某45是个什么软件 某某45是一个中国软件公司&#xff0c;提供各种软件产品和服务。其中&#xff0…

【c 语言 】malloc函数详解

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;C语言 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步&…

FFMPEG C++封装(一)(C++ FFMPEG)

1 概述 FFMPEG是一个C语言开源视音频编解码库。本文将FFMPG4.1.3进行C封装&#xff0c;形成C FFMPG库。 2 架构 架构图如下所示&#xff1a; 架构说明: Init 初始化FFMPEG库。IStream 输入流&#xff0c;FFMPEG的输入音视频文件。Packet 音视频数据包Decoder 音视频编码器F…

字符集 --java学习笔记

字符集 为了将字符存进计算机&#xff0c;所以有了字符集 标准ASCI字符集 ASCl(American standard Code for Information Interchange):美国信息交换标准代码&#xff0c;包括了英文、符号等标准ASCI使用1个字节存储一个字符&#xff0c;首尾是0&#xff0c;总共可表示128个…

HarmonyOs开发:轮播图Banner组件封装与使用

前言 轮播图在每个项目中都很常见&#xff0c;鸿蒙中在容器组件中也提供了Swiper组件&#xff0c;用于子组件滑动轮播显示&#xff0c;和前端的使用起来也是异曲同工&#xff0c;我们先看下基本的用法。 Swiper() {ForEach(["1", "2", "3", &quo…

应用案例 | 复合机器人助力智能仓储物流实现高效发展

随着智能仓储物流技术的快速发展&#xff0c;复合机器人作为一种先进的自动化设备&#xff0c;正逐渐在仓储物流领域发挥重要作用。以下是一个复合机器人在智能仓储物流的应用案例。 案例背景 某大型电商企业面临着日益增长的订单量和仓储物流压力。为了提高物流效率、降低人力…

牛角工具箱源码 轻松打造个性化在线工具箱

&#x1f389; Whats this&#xff1f; 这是一款在线工具箱程序&#xff0c;您可以通过安装扩展增强她的功能 通过插件模板的功能&#xff0c;您也可以把她当做网页导航来使用~ 觉得该项目不错的可以给个Star~ &#x1f63a; 演示地址 https://tool.aoaostar.com &#x1f…

手动实现一个扩散模型DDPM

扩散模型是目前大部分AIGC生图模型的基座&#xff0c;其本质是用神经网络学习从高斯噪声逐步恢复图像的过程&#xff0c;本文用python代码从零开始构建了一个简单的扩散模型。 理论部分 DDPM(Denoising Diffusion Probabilistic Models) 是一种在生成对抗网络等技术的基础上发展…

MQTT.fx连接新版OneNet平台的一些问题

对于使用通信主题publish给OneNET时&#xff0c;如图所示&#xff1a; 但是点击Publish后&#xff0c;出现了Broker connection lost的问题 原因在于&#xff1a;新版OneNET和旧版OneNET的通信主题不一致了&#xff0c;查阅文档获知&#xff0c;格式如下&#xff1a; $sys/{p…

二叉树的深度和高度问题-算法通关村

二叉树的深度和高度问题-算法通关村 1 最大深度问题 LeetCode104: 给定一个二叉树&#xff0c;找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明&#xff1a;叶子节点是指没有子节点的节点。 对于node&#xff08;3&#xff09;&#xff0…