子数组问题

news2024/11/15 4:44:23

目录

最大子数组和

环形子数组的最大和

乘积最大子数组

乘数为正数的最长子数组长度

等差数列划分

最长湍流子数组

单词拆分

环绕字符串中唯一的子字符串


声明:接下来主要使用动态规划来解决问题!!!

最大子数组和

题目

思路

解决子数组问题,在接下来将屡试不爽的采用“以某个位置为结尾”来分析问题。

状态表示:dp[i]表示以i位置为结尾的最大子数组和。

我们可以将上面很多情况分为两类:i单独为数组;i和前面的元素一起组成数组。

状态转移方程:dp[i]=max(nums[i],dp[i-1]+nums[i])

初始化:dp[0]=nums[0]。

填表顺序:从左往右。

返回值:dp表的最大值。

代码

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int n=nums.size();
        vector<int> dp(n+1);
        for(int i=1;i<=n;i++)
            dp[i]=max(nums[i-1],dp[i-1]+nums[i-1]);
        return *max_element(dp.begin()+1,dp.end());    
    }
};
环形子数组的最大和

题目

思路

本道题差别于上一道题的地方在于,数组是环形的,这样的话,在屡试不爽的采用“以i位置为结尾”来分析问题时,还需要通过%模运算,有点麻烦。

通过分析不难发现,环形子数组的最大和只有两种情况:

其一是最大子数组在数组中间,其二是最大子数组在头和尾。

通过上图不难发现,第一种情况可以采用求“最大子数组”的方式,由于数组的总和是确定的,那么第二种情况可以采用求“最小子数组”的方式。

状态表示:f[i]表示以i位置为结尾的最大子数组的和;

                  g[i]表示以i位置为结尾的最小子数组的和。

状态转移方程:f[i]=max(nums[i],f[i-1]+nums[i])

                         g[i]=min(nums[i],g[i-1]+nums[i])

初始化:不用初始化。

填表顺序:从左往右。

返回值:如果sum=gmin,返回fmax;否则,返回max(fmax,sum-gmin)。

代码

class Solution {
public:
    int maxSubarraySumCircular(vector<int>& nums) {
        int n=nums.size();
        vector<int> f(n+1);
        vector<int> g(n+1);
        int sum=0;
        for(int x:nums)
            sum+=x;
        for(int i=1;i<=n;i++){
            f[i]=max(nums[i-1],f[i-1]+nums[i-1]);
            g[i]=min(nums[i-1],g[i-1]+nums[i-1]);
        }
        int fmax=*max_element(f.begin()+1,f.end());
        int gmin=*min_element(g.begin()+1,g.end());
        if(gmin==sum) return fmax;
        else return max(fmax,sum-gmin);
    }
};
乘积最大子数组

题目

思路

解决子数组问题,依旧屡试不爽的采用“以某个位置为结尾”来分析问题。

状态表示:f[i]表示以i位置为结尾的最大子数组和;

                  g[i]表示以i位置为结尾的最小子数组和。

我们可以将上面很多情况分为两类:i单独为数组;i和前面的元素一起组成数组(又分为nums[i]>0  和 nums[i]<0)。

状态转移方程:

初始化:f[0]=g[0]=0

填表顺序:从左往右

返回值:f表最大值。

代码

class Solution {
public:
    int maxProduct(vector<int>& nums) {
        int n=nums.size();
        vector<int> f(n+1);
        vector<int> g(n+1);
        f[0]=g[0]=1;
        for(int i=1;i<=n;i++){
            f[i]=max(nums[i-1],max(f[i-1]*nums[i-1],g[i-1]*nums[i-1]));
            g[i]=min(nums[i-1],min(g[i-1]*nums[i-1],f[i-1]*nums[i-1]));
        }
        return *max_element(f.begin()+1,f.end());
    }
};
乘数为正数的最长子数组长度

题目

思路

解决子数组问题,依旧屡试不爽的采用“以某个位置为结尾”来分析问题。

状态表示:f[i]表示以i位置为结尾乘积为正数的最长子数组的长度;

                  g[i]表示以i位置为结尾乘积为负数的最长子数组的长度。

我们可以将上面很多情况分为两类:i单独为数组(又分为nums[i]>0  和 nums[i]<0);i和前面的元素一起组成数组(又分为nums[i]>0  和 nums[i]<0)。

状态转移方程:

初始化:不用初始化

填表顺序:从左往右。

返回值:f表最大值。

代码

class Solution {
public:
    int getMaxLen(vector<int>& nums) {
        int n=nums.size();
        vector<int> f(n+1);
        vector<int> g(n+1);
        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;
            }
        }
        return *max_element(f.begin()+1,f.end());
    }
};
等差数列划分

题目

思路

解决子数组问题,依旧屡试不爽的采用“以某个位置为结尾”来分析问题。

状态表示:dp[i]表示以i位置元素为结尾的等差数列的个数。

状态转移方程:if(nums[i-2]+nums[i]==2*nums[i-1])

                                  dp[i]=dp[i-1]+1;

初始化:不用初始化

填表顺序:从左往右。

返回值:dp表元素之和。

代码

class Solution {
public:
    int numberOfArithmeticSlices(vector<int>& nums) {
        int n=nums.size();
        if(n<3) return 0;
        vector<int> dp(n);
        for(int i=2;i<n;i++){
            if(nums[i-2]+nums[i]==2*nums[i-1])
                dp[i]=dp[i-1]+1;
        }
        int ret=0;
        for(int k:dp)
            ret+=k;
        return ret;
    }
};
最长湍流子数组

题目

思路

解决子数组问题,依旧屡试不爽的采用“以某个位置为结尾”来分析问题。

状态表示:f[i]表示以i位置元素为结尾,呈“上升”趋势的湍流子数组的长度;

                  g[i]表示以i位置元素为结尾,呈“下降”趋势的湍流子数组的长度。

状态转移方程:

初始化:全都初始化为1.

返回值:两个表的最大值。

代码

class Solution {
public:
    int maxTurbulenceSize(vector<int>& arr) {
        int n=arr.size();
        vector<int> f(n,1);
        vector<int> g(n,1);
        for(int i=1;i<n;i++){
            if(arr[i]>arr[i-1]) g[i]=f[i-1]+1;
            else if(arr[i]<arr[i-1]) f[i]=g[i-1]+1; 
        }
        int a=*max_element(f.begin(),f.end());
        int b=*max_element(g.begin(),g.end());
        return max(a,b);
    }
};
单词拆分

题目

思路

解决子数组问题,依旧屡试不爽的采用“以某个位置为结尾”来分析问题。

状态表示:dp[i]表示s字符串[0,i]区间内的子字符串可以拆分出在字典中出现的单词。

状态转移方程:dp[i]=dp[j-1]==true && s的[j,i]区间字符串有在字典中出现。【0<=j<i】

初始化:dp[0]=true

填表顺序:从左往右。

返回值:dp[n].

代码

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        unordered_set<string> hash;
        for(string str:wordDict)
            hash.insert(str);
        int n=s.size();
        s=' '+s;
        vector<bool> dp(n+1);
        dp[0]=true;
        for(int i=1;i<=n;i++){
            for(int j=i;j>=1;j--){
                if(dp[j-1] && hash.count(s.substr(j,i-j+1))){
                    dp[i]=true;
                    break;
                }
            }
        }
        return dp[n];
    }
};
环绕字符串中唯一的子字符串

题目

思路

我们依旧屡试不爽的采用“以某个位置为结尾”来分析问题。

状态表示:dp[i]表示以i位置元素为结尾的子字符串在base中出现的次数。

状态转移方程:

            if(s[i-1]+1==s[i] || (s[i-1]=='z' && s[i]=='a'))

                dp[i]+=dp[i-1];

初始化:全都初始化为1.

返回值:由于题目中要求统计并返回 s 中有多少 不同非空子串 也在 base 中出现,因此我们需要做“去重”操作,对于两个相同字符,只需统计以该字符结尾在base中出现次数最多的那个即可,然后返回去重后的总和。

代码

class Solution {
public:
    int findSubstringInWraproundString(string s) {
        int n=s.size();
        vector<int> dp(n,1);
        for(int i=1;i<n;i++)
            if(s[i-1]+1==s[i] || (s[i-1]=='z' && s[i]=='a'))
                dp[i]+=dp[i-1];
        int arr[26];
        for(int i=0;i<n;i++){
            arr[s[i]-97]=max(arr[s[i]-97],dp[i]);
        }
        int ret=0;
        for(int i=0;i<26;i++)
            ret+=arr[i];
        return ret;
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构进阶——使用数组实现栈和队列详解与示例(C,C#,C++)

文章目录 1、数组实现栈栈的基本操作C语言实现C#语言实现 2、 数组实现队列队列的基本操作C语言实现C# 语言实现C语言实现 总结 在编程世界中&#xff0c;数据结构是构建高效算法的基石。栈和队列作为两种基本的数据结构&#xff0c;它们的应用非常广泛。本文将带领大家使用C&a…

【OrangePi AIpro】: 探索AI加成的开源硬件魅力

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 Orange Pi: 探索开源硬件的魅力引言Orange Pi概述OrangePi AIPro产品介绍试用体…

STM32第二十课:FreeRTOS任务管理和信号量

目录 一、任务管理方式二、任务堆栈溢出检测三、二值信号量&#xff08;任务同步&#xff09;四、计数信号量五、互斥信号量六、队列 一、任务管理方式 1.任务创建成功后会添加到就绪链表中&#xff0c;开启调度器&#xff0c;此时任务调度器会去就绪链表中找优先级最高的任务执…

数据增强新方法SUMix:解决Mixup混合后的图像的内容与其标签不匹配问题

数据增强新方法SUMix&#xff1a;解决Mixup混合后的图像的内容与其标签不匹配问题 提出背景当前混合方法的问题MixUp 操作标签混合混合交叉熵&#xff08;MCE&#xff09;混合交叉熵&#xff08;MCE&#xff09;的核心作用混合交叉熵&#xff08;MCE&#xff09;的功能 CutMix原…

$accumulator(聚合)

$accumulator 是 MongoDB 聚合管道中用于自定义数据处理逻辑的一个算子&#xff0c;它允许用户使用 JavaScript 编写代码来控制数据的初始化、累积、合并和最终输出。下面是对 $accumulator 各个部分的详细解释&#xff1a; init: 这是一个 JavaScript 函数&#xff0c;用于初…

数据结构回顾(Java)

1.数组 线性表 定义的方式 int[] anew int[10] 为什么查询快&#xff1f; 1.可以借助O(1)时间复杂度访问某一元素&#xff0c; 2.地址连续&#xff0c;逻辑连续 3.数组长度一旦确定就不可以被修改 当需要扩容的时候需要将老数组的内容复制过来 在Java中数组是一个对象 Ar…

多样化数据可视化方法的全面示例:基于Python的多样化数据可视化

文章目录 前言代码效果展示 前言 本文演示了使用Python进行温度数据的多样化可视化方法。通过导入、处理和分析气象数据&#xff0c;我们生成了多种图表&#xff0c;包括直方图、核密度估计图、箱型图、小提琴图、条形图、山脊图、经验累积分布函数图和折线图。这些图表帮助我…

国内体外诊断行业翘楚『迈克生物』SRM项目启动,企企通赋能IVD产业打造高效采购供应链体系

IVD行业&#xff08;体外诊断行业&#xff09;在医疗领域被誉为“医生的眼睛”&#xff0c;是现代检验医学的重要构成部分&#xff0c;在临床应用中贯穿了疾病预防、初步诊断、治疗方案选择、疗效评价等疾病治疗的全过程&#xff0c;在现代医学疾病诊断中发挥着重要作用。 随着…

springboot1——快速构建项目

需求 第一步&#xff1a;创建maven工程(非web项目) 第二步&#xff1a;导入起步依赖 点击&#xff1a; 下拉复制&#xff1a; 粘贴&#xff1a;&#xff01;&#xff01;这是springboot工程需要继承的父工程 下拉复制&#xff1a; 粘贴&#xff1a;&#xff01;&#xf…

JAVA:常用的链表指南

请关注微信公众号&#xff1a;拾荒的小海螺 博客地址&#xff1a;http://lsk-ww.cn/ 1、简述 链表是一种常见的数据结构&#xff0c;它通过一系列节点&#xff08;Node&#xff09;来表示一个序列。每个节点包含数据和指向下一个节点的引用。链表的种类有很多&#xff0c;包括…

网络文件系统—NFS

目录 一、概述 二、NFS挂载原理 三、NFS相关协议及软件安装管理 1.协议&#xff1a; 2.软件&#xff1a; 四、NFS系统守护进程 五、NFS服务器的配置 六、NFS服务器的启动与停止 1. 启动NFS服务器 2.查询NFS服务器状态 3.停止NFS服务器 4.设置NFS服务器的自动启动状…

games103作业2(未完)

PBD方法 首先是每个质点的力的分析&#xff0c;不考虑碰撞和弹簧弹力的情况下&#xff0c;每个质点受重力的影响&#xff0c;所以需要对每个质点进行速度和位置的重力影响更新。 float t 0.0333f; float damping 0.99f; int[] E; float[] L; Vector3[] V; Vector3 gra…

【数学建模】——数学规划模型

目录 一、线性规划&#xff08;Linear Programming&#xff09; 1.1 线性规划的基本概念 1.2 线性规划的图解法 模型建立&#xff1a; 二、整数规划&#xff08;Integer Programming&#xff09; 2.1 整数规划的基本概念 2.2 整数规划的求解方法 三、非线性规划&#x…

<数据集>绝缘子缺陷检测数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;2139张 标注数量(xml文件个数)&#xff1a;2139 标注数量(txt文件个数)&#xff1a;2139 标注类别数&#xff1a;8 标注类别名称&#xff1a;[insulator, broken disc, pollution-flashover, Two glass, Glassdirt…

220V降压5ⅤIC-AH8652

220V降压至5V的IC - AH8652 在电子设计中&#xff0c;电压转换是一个常见的需求&#xff0c;尤其是在需要将高电压转换为低电压以供电给微电子设备时。AH8652是一款专为降压转换设计的集成电路&#xff0c;它能够将220V的交流输入电压转换为稳定的5V直流输出&#xff0c;非常适…

Camunda如何通过外部任务与其他系统自动交互

文章目录 简介流程图外部系统pom.xmllogback.xml监听类 启动流程实例常见问题Public Key Retrieval is not allowed的解决方法java.lang.reflect.InaccessibleObjectException 流程图xml 简介 前面我们已经介绍了Camunda的基本操作、任务、表&#xff1a; Camunda组件与服务与…

spring6之容器:IOC

容器&#xff1a;IOC 控制反转&#xff08;Ioc&#xff09; IoC容器在Spring的实现 Spring 的 IoC 容器就是 IoC思想的一个落地的产品实现。IoC容器中管理的组件也叫做 bean。在创建 bean 之前&#xff0c;首先需要创建IoC 容器。Spring 提供了IoC 容器的两种实现方式&#xf…

华为HCIP Datacom H12-821 卷39

1.填空题 请2001 :0DB8:0000:C030:0000: 000: 09A0:CDEF地址进行压缩。() (若答案中存在字母&#xff0c;请采用大写格式) 参考答案&#xff1a;2001 :DB8:0:C030: :9A0:CDEF 解析&#xff1a; IPv6地址的表示方法 IPv6地址总长度为128比特&#xff0c;通常分为8组&#xff0c…

防御综合实验作业2

办公区设备可以通过电信链路和移动链路上网(多对多的NAT&#xff0c;并且需要保留一个公网IP NAT策略&#xff1a; 安全策略&#xff1a; 测试&#xff1a; 分公司设备可以通过总公司的移动链路和电信链路访问到Dmz区的http服务器 是怎么转换的&#xff0c;首先分公司的用户需…

温度如何影响输入失调电压

目录 一、概念理解 二、仿真理解 一、概念理解 在手册中有这样一个参数&#xff1a;输入失调电压漂移&#xff08;input offset voltage drift / offset drift&#xff09; 以上图为例&#xff0c;这个参数理解为&#xff1a;常温下&#xff08;25℃&#xff09;每增减1摄氏度…