【C++】双指针算法:复写零

1.题目

别看这是一道简单题,它的通过率低于一些中等甚至困难的题目!

大大增加这道题目难度的是最后一句话:1.不可越界写入。2.就地修改。

如果可以再创建一个数组的话,那么这道题目就会非常简单,但这道题目必须要求在原数组上修改就需要注意很多细节!

2.算法思路

同样,我们需要两个指针:cur和dest。

cur负责遍历数组,判断所读取的元素是0还是非0。

dest负责修改数据。

现在两个指针分工明确,就需要确定是从左往右遍历数组还是从右往左遍历数组。

举个例子:arr={1,0,2,3};

先试试从左往右遍历数组:

cur读取第一个元素是非0,dest对数组不做处理。

cur读取第二个元素是0,dest将第二个,第三个元素修改成0。此时数组变成:arr={1,0,0,3};从这一步开始,后面就全错了!因为第三个元素被改成0了,cur已经读读不到原来的数据了,结果就是dest将后面的数据全部改成零!

看来只能从右往左遍历数组:

这次举题目中示例一的例子:arr={1,0,2,3,0,4,5,0};

从这个例子中结果,我们发现cur指针最多遍历到元素4就不会往后遍历了,如果我们先确定cur读取的最后一个数据的位置,让cur从那个位置从后往前遍历,让dest从后往前修改就不会出现0把原来还没读取的数据覆盖的情况。

但这种方法需要考虑一个边界情况:如果数组是arr={1,0,2,3,0,4};

修改后的结果就是arr={1,0,0,2,3,0};要特别注意dest从后往前修改数组时,最后一个0只写了一遍!把这个边界情况解决后就可以完成这道题目啦!

3.提交结果和代码

提交结果:

代码:

这个代码是我第一次写这道题目时写的代码,并不是最精简的,读起来有些费劲,我在后面给出了简化版的

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int size=arr.size(),cur=0,dest=-1;
        //用cur找到数组需要复写的最后一个数
        while(1){
            if(size==0)
                break;
            if(arr[cur]){
                dest++;
                if(dest<size-1)
                    cur++;
                else
                    break;
            }
            else{
                dest+=2;
                if(dest<size-1)
                    cur++;
                else
                    break;
            }
        }
        if(dest==size){ //处理边界情况
            arr[--dest]=arr[cur--];
            dest--;
        }
        while(cur>=0){ //dest前置--和后置--尽量不要混合使用,否则很可能在数组同一个位置会写入两次,或有的位置会漏写
            if(arr[cur]==0){
                arr[dest--]=0;
                arr[dest--]=0;
                cur--;
            }
            else{
                arr[dest--]=arr[cur--];
            }
            
        }
    }
};

 这是简化后的代码,结果更清晰一些:

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int size=arr.size(),cur=0,dest=-1;
        //用cur找到数组需要复写的最后一个数
        while(cur<size){
            if(arr[cur]) dest++;
            else dest+=2;
            if(dest>=size-1) break;
            cur++;    
        }
        if(dest==size){ //处理边界情况
            arr[dest-1]=arr[cur];
            dest-=2;cur--;
        }
        while(cur>=0){ //dest前置--和后置--尽量不要混合使用,否则很可能在数组同一个位置会写入两次,或有的位置会漏写
            if(arr[cur]==0){
                arr[dest--]=0;
                arr[dest--]=0;
                cur--;
            }
            else arr[dest--]=arr[cur--];
        }
    }
};

时间复杂度分析:

大约遍历了两次数组,时间复杂度:O(n)。

空间复杂度分析:

定义了三个变量,空间复杂度:O(1)。

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

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

相关文章

网络工程师---第十天

ARP表&#xff1a; 提起ARP表必然先想起ARP&#xff08;address resolution protocol&#xff09;协议&#xff0c;地址解析协议。 在实际应用中&#xff0c;我们经常遇到这样的问题&#xff1a;已知一个机器的IP地址&#xff0c;但在实际网络的链路上传送数据帧时&#xff0c;…

Redis安装部署教程

文章目录 Redis安装部署 Redis安装部署 &#xff08;1&#xff09; 下载xx.msi安装包&#xff0c;可以通过该下载地址进行下载。 &#xff08;2&#xff09; 双击下载的安装包进行安装。 &#xff08;3&#xff09; 选择安装目录&#xff08;默认C盘&#xff09;&#xff…

Kali Linux扩容(使用图形化界面)

因为今天在拉取vulhub中的镜像的时候报错空间不够&#xff0c;因为最开始只给了20GB的空间&#xff0c;所以现在需要扩容了&#xff0c;结合了一下网上的找到了简便的解决方法 1.首先虚拟机设置->磁盘->扩展 小插曲&#xff1a;在对虚拟机磁盘进行扩容以后&#xff0c;…

Flask-SQLAlchemy 中使用显式主主数据库设置

1、问题背景 在一个 Flask-SQLAlchemy 项目中&#xff0c;用户想要使用显式主主数据库设置。具体而言&#xff0c;他想要能够从默认数据库中读取数据&#xff0c;并将数据持久化到两个主数据库中。他希望知道是否可以使用 Flask-SQLAlchemy 和 binds 来实现这一目标。 2、解决…

解决宝塔面板无法访问(无法访问或拒绝链接)

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;Linux ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 问题如下&#xff1a; 本人设置了授权IP&#xff0c;但是有些问题&#xff0c;所以是打算取消授权IP 重…

使用QQ邮箱进行登录验证

使用场景不多说&#xff0c;接下来直接看实现~ 登录到QQ邮箱&#xff0c;进入设置 打开IMAP/SMTP服务&#xff0c;记得把授权码记录下来&#xff0c;后面配置文件中需要用到 新建application的配置文件 spring:mail:# 指定邮件服务器地址host: smtp.qq.comusername: 你自己的q…

分布式与一致性协议之拜占庭将军问题(一)

拜占庭将军问题 概述 拜占庭将军问题其实是借拜占庭将军故事展现了分布式共识问题&#xff0c;探讨和论证了解决的办法。实际上&#xff0c;拜占庭将军问题是分布式领域最复杂的一个容错模型&#xff0c;一旦搞懂了它&#xff0c;久能掌握分布式共识问题的解决思路&#xff0…

NTLM认证

文章目录 1.概念(1) 本地认证(2) SAM(3) NTLM Hash(4) NTLM 和 NTLM Hash(5) NTLM v2 1.概念 (1) 本地认证 Windows不存储用户的明文密码&#xff0c;它会将用户的明文密码经过加密后存储在 SAM (Security Account Manager Database&#xff0c;安全账号管理数据库)中。 (2)…

Marching Cubes算法

Marching Cubes算法 1. 简介2. 算法原理的理解2.1 如何找到面经过的这些小块(六面体)&#xff1f;2.2 找到后&#xff0c;如何又进一步的找到面与这些小块(六面体)的交点&#xff1b;2.3 这些交点按照怎么的拓扑连接关系连接&#xff0c;是怎么操作的&#xff1f; 3. 总结4. 参…

【链表】Leetcode 两数相加

题目讲解 2. 两数相加 算法讲解 我们这里设置一个头结点&#xff0c;然后遍历两个链表&#xff0c;使用一个flag记录相加的结果和进位&#xff0c;如果两个链表没有走到最后或者进位不等于0&#xff0c;我们就继续遍历处理进位&#xff1b;如果当前的链表都遍历完成了&#x…

基于springboot实现的摄影跟拍预定管理系统

开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven…

【系统分析师】多媒体技术与知识产权标准化

文章目录 一、多媒体技术1、音频2、图像3、媒体的分类4、有损压缩和无损压缩5、多媒体标准 二、知识产权标准化1、保护范围和对象2、保护期限3、知识产权人确定4、侵权判定5、标准化 一、多媒体技术 1、音频 # 声音文件格式 .wav .mp3 .ra .mid .snd .au .aif .voc2、图像 # 彩…

一招下载transformers真不用网上那些教程(我试了1*mol多次才知道)

pip很多是2 然而&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;…

ASP.NET大文件分片上传

ASP.NET大文件分片上传&#xff0c;C#上传大型视频文件到服务器,解决方案&#xff0c;用C# 实现断点续传 (HTTP)&#xff0c;ASP.NET实现文件夹的上传和下载&#xff0c;.NET使用WEBUPLOADER做大文件的分块和断点续传&#xff0c;ASP.NET实现文件上传和下载&#xff0c;完美解决…

fastgpt、dify功能分析比较

目录 前言 一、dify、fastgpt是什么&#xff1f; 二、同场pk 1.大模型接入 2.chat&#xff08;最简应用&#xff09; 3.发布应用 4.知识库 5.workflow 6.其他 三、一些point记录 总结 前言 现在都开始AI应用开发&#xff0c;何谓AI应用&#xff0c;起码要和AI大模型…

13-LINUX--消息队列

一.消息队列 1.消息队列&#xff1a;消息队列为一个进程向另一个进程发送一个数据块提供了条件&#xff0c;每个数据块会包含一个类型。 2.相关函数 1>.msgget(key_t key,int msgflg) : 创建消息队列 2>. msgsnd&#xff1a;把消息添加到消息队列 3>.msgrcv &#xf…

【iOS开发】(四)react Native第三方组件五个20240419-20

react native 外的 第三方组件 目录标题 react native 外的 第三方组件&#xff08;一&#xff09;与rn核心组件的使用步骤区别&#xff1a;&#xff08;二&#xff09;第三方组件概览1 WebView2 Picker3 Swiper4 AsyncStorage5 Geolocation6 Camera (三)详细学习1 WebViewCoco…

C语言 分支控制语句之 if

然后 我们来说 流程控制语句之 if 选择控制结构 是通过 分支语句来实现的 其中 包括 单分支选择语句通过 (if) 来实现 双分支语句通过 (if) 和 (else) 实现 多分支语句通过 (if) (else if) (else) 实现 对于单分支来讲 它控制的语句就是 要嘛做 要嘛不做 好比如 放假了 你是…

MySQL基础之单表操作(定义DDL,增删改DML,查DQL)

目录 一、概述1.1 什么是数据库1.2 连接MySQL1.3 数据模型1.4 SQL语句的分类1.5 数据类型 二、数据库设计-DDL2.1 数据库层面2.2 数据表层面创建表约束查询修改add,modify,change,drop,rename删除 三、数据库操作-DML3.1 添加数据insert3.2 修改数据update3.3 删除数据delete 四…

插值与重采样在AI去衣技术中的关键作用

在人工智能&#xff08;AI&#xff09;的众多应用中&#xff0c;去衣技术作为一种新兴的图像处理技术&#xff0c;逐渐引起了广泛关注。这项技术不仅涉及复杂的计算机视觉和深度学习算法&#xff0c;还需要对图像处理中的插值与重采样技术有深入的理解。本文将详细探讨插值与重…