【力扣每日一题】2023.7.20 环形子数组的最大和

news2024/12/29 8:33:33

题目:

示例:

分析:

题目描述的有点复杂,特别是那个公式,一看到我就烦.

其实意思就是找出一个子数组(连续),要求这个子数组的和是所有子数组中最大的,并且这个数组是环形的,意思就是我这个子数组可以从原数组的尾部开始,到原数组的头部结束,就是原数组的首尾是连同的.

那么我第一反应就是将原数组后面再连接一个原数组得到新数组,例如这样: 

这样就是首尾相连了,并且只要我把子数组的长度控制在小于等于原数组,那么取到的子数组就是等于在原数组首尾相连的情况下取到的子数组(即不会重复取同一个元素).

这时候再取前缀和,获取最大的子数组和(长度要控制在小于等于原数组),将两个索引的前缀和相减就是两个索引之间的元素之和(不理解的同学再仔细理解理解):

 代码在下面,总之结果是超时,就是提供一种思路.(回头看看代码,发现时间复杂度确实有点高)

以下思路参考力扣外国站大佬,大佬的思路确实厉害:

LeetCode - The World's Leading Online Programming Learning Platform

我们可以发现要取首尾相连的数组的最大子数组和,其实一共就两种情况,一种是常规情况,子数组就在原数组的中间:

 另外一种情况是这样的,子数组的开头在原数组的末尾,结尾在子数组的开头:

 如果是第一种情况,我们就可以参考力扣第53题最大子数组和,那题和本题基本一致,只不过本题的数组是头尾相连的,但如果是第一种情况,就没有利用到首尾相连的这一特性,因此可以直接套用53题的解法(具体思路就不说了,直接看代码叭)

//https://leetcode.cn/problems/maximum-subarray/
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        vector<int>dp(nums.size(),nums[0]);
        int res=dp[0];
        for(int i=1;i<nums.size();i++){
            dp[i]=max(0,dp[i-1])+nums[i];
            res=max(res,dp[i]);
        }
        return res;
    }
};

那么我们就算是把第一种情况给解决掉了,此时就剩第二种情况,其实第二种情况我们可以发现和第一种情况也很想,都是在原数组的中间有这么一段连续子数组,那么它们这两段连续的子数组有什么联系呢?

我们可以发现在第一种情况中,在原数组中间的的这段连续子数组是所有子数组里和最大的子数组,也就是我们要求的.

而第二种情况中,在原数组中间的这段连续子数组是什么,我们乍一看还看不出来是什么,其实中间这段是所有子数组里和最小的子数组,我把一个首尾相连的数组里和最小的连续子数组删去,剩下的不就是我能凑到的和最大的连续子数组了?

可能不太好理解,我举一个比较极端的例子给大家看看:

 如上图所示,中间这段是连续子数组的和为-200,而整个数组的和为-196,如果我把中间的害群之马和最小的子数组删掉,那么得到的首尾相连的最大子数组的和不就是整个数组的和减去最小连续子数组的和等于 -196-(-200) =4 了?

那么我们就算是找到规律了,我们只需要按照上面53题的做法使用动态规划来分别获取在首尾不相连的情况下,最大的连续子数组和最小的连续子数组,再分别比较第一种情况和第二种情况即可.

假设为第一种情况,那么结果就是找出的最大连续子数组的和.假设是第二种情况,那么结果就是整个数组的和减去最小的连续子数组.在两种情况都假设完之后,返回结果最大的一种情况.

但其实我们忽略了另一种极端情况,那就是整个数组都是负数的情况.

在这种情况下,我们应该返回的是整个数组中最小的那个负数,但按照我们上面的推导,我们会返回0,因为我们求出来最大的连续子数组的和确实是整个数组中最小的负数,但是整个数组的和减去最小的连续子数组的和的结果却是0(最小的连续子数组就是整个数组,如果整个数组减去最小的连续子数组就相当于是我们一个元素都不取,但是这样是不符合题意的,我们至少需要取一个),比最大的连续子数组的和更大,因此在整个数组都是负数的情况下我们返回的是0.

我们只需要在返回结果的时候多一个判断就可以了:

return Max>0 ? max(Max,Sum-Min) : Max;

 在最大的连续子数组的和大于0的时候我们再比较两种情况谁更大,然后返回更大的一个数.

如果最大的连续子数组的和小于0,这时就是整个数组都是负数的情况了,我们则不用比较,直接返回最大的连续子数组的和就可以了.

代码+运行结果:

前缀和,但是超时,提供一种解题思路.

class Solution {
public:
    int maxSubarraySumCircular(vector<int>& nums) {
        //前缀和超时
        int n=nums.size();
        int res=nums[0];
        int temp=0;
        vector<int>newNums(2*n),tempNums(2*n);
        for(int i=0;i<2;i++){
            for(int j=0;j<n;j++) newNums[i*n+j]=nums[j];
        }
        for(int i=0;i<2*n;i++){
            tempNums[i]=temp;
            temp+=newNums[i];
        }
        for(int i=0;i<n;i++){
            for(int j=i+1;j<2*n && j-i<n+1;j++){
                res=max(res,tempNums[j]-tempNums[i]);
            }
        }
        return res;
    }
}
class Solution {
public:
    int maxSubarraySumCircular(vector<int>& nums) {
        //参考的https://leetcode.com/problems/maximum-sum-circular-subarray/solutions/178422/One-Pass/的动态规划
        int n=nums.size();
        vector<vector<int>>dp(2,vector<int>(n,nums[0]));
        int Max=nums[0],Min=nums[0],Sum=nums[0];
        for(int i=1;i<n;i++){
            Sum+=nums[i];
            dp[0][i]=max(0,dp[0][i-1])+nums[i];
            dp[1][i]=min(0,dp[1][i-1])+nums[i];
            Max=max(Max,dp[0][i]);
            Min=min(Min,dp[1][i]);
        }
        return Max>0 ? max(Max,Sum-Min) : Max;
    }
};

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

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

相关文章

Nginx文件下载预览加权限验证的思考和实现

做的项目中多个模块涉及到附件、图片、PDF/Excel等文件的处理&#xff0c;包括预览、导出和下载等功能。对于体积较小的文件&#xff0c;可以直接由后端以流形式传输给前端处理&#xff1b;而较大的文件则需要通过nginx进行转发。但是如果nginx中不设置鉴权服务&#xff0c;可能…

帖子列表和SerializerMixin注意事项

帖子序列化 继承SerializerMixin 即可调用to_dict()序列化 后端 class PostModel(db.Model, SerializerMixin):serialize_only ("id", "title", "content", "create_time", "board", "author")__tablename__ …

Ubuntu22.04上部署Lua开发环境

需求背景 想在Ubuntu22.04上搭建一下Lua的开发环境&#xff0c;其实步骤比较简单的&#xff0c;此文章也适用于Ubuntu主机环境搭建Lua,如果想在在Ubuntu内部署一个容器&#xff0c;然后在容器内搭建Lua的环境&#xff0c;可以先参考容器的创建过程 ubuntu22.04上如何创建有pri…

android adb命令获取处于当前屏幕的Activity

android adb命令获取处于当前屏幕的Activity 使用adb命令&#xff1a; adb shell dumpsys activity activities 输出&#xff0c;例如: ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities) Display #0 (activities from top to bottom): * Task{38ef601 #5281 typ…

C++-----list

本期我们来讲解list&#xff0c;有了string和vector的基础&#xff0c;我们学习起来会快很多 目录 list介绍 ​编辑 list常用接口 insert erase reverse sort merge unique remove splice 模拟实现 基础框架 构造函数 push_back 迭代器 常见问题 const迭代器 …

BEVPoolv2 A Cutting-edge Implementation of BEVDet Toward Deployment 论文学习

Github Repo: https://github.com/HuangJunJie2017/BEVDet/tree/dev2.0 Arxiv Paper: https://arxiv.org/abs/2211.17111 1. 解决了什么问题&#xff1f; 多相机 3D 目标检测是自动驾驶领域的基本任务&#xff0c;受到学术界和工业界的大量关注。Lift-Splat-Shoot view trans…

Linux基础IO(一)

Linux基础IO 文章目录 Linux基础IOC语言中的文件操作c语言文件打开方式C语言文件操作函数 系统文件操作stdin/stdout/stderropeanclosewriteread 文件描述符重定向什么是重定向dup2 C语言中的文件操作 我们通过两个代码复习一下C语言中的文件操作&#xff1a; int main() {FI…

uniapp-开发APP使用自定义插件

uniapp-开发APP使用自定义插件 需求背景&#xff1a; 项目组开发了一个APP需要使用到打印机的功能、所以需要通过打印机厂商提供的jdk包结合自己的业务融合到uniapp 中。 首先你需要一个懂开发android开发的同事、让他帮忙配合写一些调用方法&#xff08;调用打印机提供的一些…

态势标绘专题介绍

介绍 这个专栏是专门针对基于Cesium来实现态势标绘的专题专栏,专栏主要实现了30余种态势几何形状的标绘和编辑、文本的标绘和编辑、图片的标绘和编辑以及简单模型的标绘,同时支持标绘结果的导出以及导入。包括最终编写成的一个完整的Vue3.2+TS+Cesium1.107.2的标绘组件。专栏…

【STL】list用法试做_底层实现

目录 一&#xff0c;list 使用 1. list 文档介绍 2. 常见接口 1. list中的sort 2. list sort 与 vector sort效率对比 3. 关于迭代器失效 4. clear 二&#xff0c;list 实现 1.框架搭建 2. 迭代器类——核心框架 3. operator-> 实现 4. const——迭代…

c++11 标准模板(STL)(std::basic_filebuf)(二)

定义于头文件 <fstream> template< class CharT, class Traits std::char_traits<CharT> > class basic_filebuf : public std::basic_streambuf<CharT, Traits> std::basic_filebuf 是关联字符序列为文件的 std::basic_streambuf 。输入序…

基于AOP实现登录日志和操作日志(新手入门版)

基于AOP实现登录日志和操作日志 目录结构代码PostMan测试代码控制台查看输出解析成JSON如果你觉得对你有帮助的话&#xff0c;请点赞收藏 目录结构 代码 package com.demo.mymaintest.constants;import java.lang.annotation.Documented; import java.lang.annotation.ElementT…

在Debian 12 上安装 PHP 5.6, 7.4

环境&#xff1a;Debian 12 Debian 12 默认的PHP版本为 8.2 如果直接安装php7.4就出现下面的报错&#xff1a; sudo apt-get install libapache2-mod-php7.4 php7.4 php7.4-gd php7.4-opcache php7.4-mbstring php7.4-xml php7.4-json php7.4-zip php7.4-curl php7.4-imap p…

【人工智能】神经网络、前向传播、反向传播、梯度下降、局部最小值、多层前馈网络、缓解过拟合的策略

神经网络、前向传播、反向传播 文章目录 神经网络、前向传播、反向传播前向传播反向传播梯度下降局部最小值多层前馈网络表示能力多层前馈网络局限缓解过拟合的策略前向传播是指将输入数据从输入层开始经过一系列的权重矩阵和激活函数的计算后,最终得到输出结果的过程。在前向…

HarmonyOS/OpenHarmony应用开发-Stage模型UIAbility组件使用(六)

UIAbility组件间交互&#xff08;设备内&#xff09; UIAbility是系统调度的最小单元。在设备内的功能模块之间跳转时&#xff0c;会涉及到启动特定的UIAbility&#xff0c;该UIAbility可以是应用内的其他UIAbility&#xff0c;也可以是其他应用的UIAbility&#xff08;例如启…

unity 调用C++追踪物体后的位姿通过 dll,左右手坐标转化2

外参矩阵转四元数,左右手坐标系转化1_天人合一peng的博客-CSDN博客 在之前1的基础上更新 通过定位已经求得了物体的4*4的位姿矩阵&#xff0c;将其变化为四元数并从opengl的右手坐标转化为unity的左手坐标系。 body2world_pose().matrix()为计算得到的4*4的位姿矩阵 例 body…

Go语言之结构体

在实际开发中&#xff0c;我们可以将一组类型不同的、但是用来描述同一件事物的变量放到结构体中。例如&#xff0c;在校学生有姓名、年龄、身高、成绩等属性&#xff0c;学了结构体后&#xff0c;我们就不需要再定义多个变量了&#xff0c;将它们都放到结构体中即可。 在Go语言…

基于linux下的高并发服务器开发(第三章)- 3.7 线程属性

int pthread_attr_init(pthread_attr_t *attr);- 初始化线程属性变量int pthread_attr_destroy(pthread_attr_t *attr);- 释放线程属性的资源int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);- 获取线程分离的状态属性int pthread_attr_setdet…

【Redis】所以延迟双删有啥用

文章目录 1、何为延时双删2、常用缓存策略2.1、介绍2.2、先删缓存后更库2.3、先更库后删缓存2.4、使用场景 3、延时双删实现4、为什么要使用延时双删5、方案选择6、延时双删真的完美吗7、如何确定延时的时间 1、何为延时双删 延迟双删&#xff08;Delay Double Delete&#xf…

Jupyter 安装、简单操作及工作路径更换

一、Jupyter下载安装 pip install jupyterAnaconda是Python另一个非常流行的发行版&#xff0c;它之后有着自己的叫做“conda”的安装工具。用户可以使用它来安装很多第三方包。然而&#xff0c;Anaconda会预装很多包&#xff0c;包括了Jupyter Notebook,所以若已经安装了Anac…