(2)双指针练习:复写零

复写零

题目链接:1089. 复写零 - 力扣(LeetCode)

给你一个长度固定的整数数组 arr ,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。
注意:请不要在超过该数组长度的位置写入元素。请对输入的数组 就地 进行上述修改,不要从函数返回任何东西。

思路解析:

本题有两种思路:

  1. 暴力复写
  2. 双指针原地复写
  • 暴力复写

暴力的方法很简单,因为是复写,所以只需要遇到0先将0位置后面的数据进行挪动覆盖,但是注意要从尾部开始挪动,挪动完毕后在当前位置的下一个位置插入一个数字0,让指针走两步

暴力复写参考代码:

/*
 * @lc app=leetcode.cn id=1089 lang=cpp
 *
 * [1089] 复写零
 */

// @lc code=start
// 暴力解法
class Solution
{
public:
    void duplicateZeros(vector<int> &arr)
    {
        for (int i = 0; i < arr.size(); i++)
        {
            if (arr[i] == 0 && arr.size() - 2 > 0)
            {
                int j = arr.size() - 2;
                while (j + 1 < arr.size() && j > i)
                {
                    arr[j + 1] = arr[j];
                    j--;
                }
                if (i + 1 < arr.size())
                {
                    arr[++i] = 0;
                }
            }
        }
    }
};
//  @lc code=end
  • 双指针原地复写

对于双指针算法来说,有两种实现方式,第一种是异地复写,即开辟一个新空间,基本思路为遇到非0数字复写一次,遇到数字0复写两次,但是这个算法的空间复杂度为O(N),所以考虑原地复写

双指针——异地复写参考代码:

/*
 * @lc app=leetcode.cn id=1089 lang=cpp
 *
 * [1089] 复写零
 */

// @lc code=start
// 双指针——异地操作
class Solution
{
public:
    void duplicateZeros(vector<int> &arr)
    {
        vector<int> ret;
        ret.resize(arr.size());
        int cur = 0;
        int dest = 0;
        while (dest < ret.size())
        {
            if (arr[cur] == 0)
            {
                dest++;
                dest++;
                cur++;
            }
            else
            {
                ret[dest++] = arr[cur++];
            }
        }
        arr.assign(ret.begin(), ret.end());
    }
};
//  @lc code=end

原地复写和异地复写的思路是一致的,但是原地复写不可以从源数组的第一个元素开始复写,这样会导致遇到数字0时后面的内容全部都覆盖为0,正确的做法是从最后一个待复写元素开始向最后一个位置进行复写,再依次往前遍历执行复写操作,复写具体操作为:

  1. 遇到非0数字向dest位置覆写当前cur位置的数字
  2. 遇到0数字向dest位置和dest-1位置复写两个0
  3. cur向前移动1步

现在的问题就是如何找到最后一个待复写的元素,可以考虑一次正向遍历,但是在这一次遍历中不进行任何的复写操作,具体操作为:

  1. cur所在位置是非0的数字:dest移动一步
  2. cur所在位置是数字0:dest移动两步
  3. 判断dest是否到最后一个元素的位置
  4. cur移动一步

遍历完成后cur所指向的位置即为最后一个待复写的元素,而dest所指向的位置即为最后一个元素的位置,如图所示:

但是此时需要注意一种特殊情况:

当指向的待复写元素是0时,那么此时dest指向的位置已经超出了数组的范围,如果此时在dest位置复写时就会出现越界访问的情况,那么此时需要进行边界修正,修正方法如下:

  1. dest-1的位置处覆写数字0
  2. cur向前走动一步
  3. dest向前走动两步

处理完边界情况后就可以进行正常的复写操作过程

双指针——原地复写参考代码:

/*
 * @lc app=leetcode.cn id=1089 lang=cpp
 *
 * [1089] 复写零
 */

// @lc code=start
// 双指针——原地操作
class Solution
{
public:
    void duplicateZeros(vector<int> &arr)
    {
        int cur = 0, dest = -1;
        int sz = arr.size();
        // 找到结果数组中的最后一个重写的元素的位置
        while (cur < sz)
        {
            if (arr[cur] == 0)
            {
                dest += 2;
            }
            else
            {
                dest++;
            }

            if (dest >= sz - 1)
            {
                break;
            }
            cur++;
        }

        // 修正边界情况
        if (dest == sz)
        {
            arr[dest - 1] = 0;
            cur--;
            dest -= 2;
        }

        // 覆写
        while (cur >= 0)
        {
            if (arr[cur])
            {
                arr[dest--] = arr[cur--];
            }
            else
            {
                arr[dest--] = 0;
                arr[dest--] = 0;
                cur--;
            }
        }
    }
};
//  @lc code=end

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

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

相关文章

WebSocket or SSE?即时通讯的应用策略【送源码】

最近在研究H5推送&#xff0c;发现除了我们常用的WebSocket以外&#xff0c;其实还有一种协议也能实现H5推送&#xff0c;那就是SSE协议。 而且&#xff0c;当前主流的大模型平台&#xff0c;比如ChatGPT、通义千问、文心一言&#xff0c;对话时采用的就是SSE。 什么是SSE协议…

基于HTML5和CSS3搭建一个Web网页(一)

倘若代码中有任何问题或疑问&#xff0c;欢迎留言交流~ 网页描述 创建一个包含导航栏、主内容区域和页脚的响应式网页。 需求: 导航栏: 在页面顶部创建一个导航栏&#xff0c;包含首页、关于我们、服务和联系我们等链接。 设置导航栏样式&#xff0c;包括字体、颜色和背景颜…

识物扫一扫识别植物怎么做?6个软件教你轻松识别植物

识物扫一扫识别植物怎么做&#xff1f;6个软件教你轻松识别植物 识别植物可以通过专门的植物识别应用来实现。以下是六款可以帮助您轻松识别植物的软件&#xff1a; 1.一键识别王&#xff1a;这款软件有着强大的植物识别服务&#xff0c;用户可以通过拍照或上传图片来识别植物…

算法学习笔记(5.0)-基于比较的高效排序算法-归并排序

##时间复杂度O(nlogn) 目录 ##时间复杂度O(nlogn) ##递归实现归并排序 ##原理 ##图例 ##代码实现 ##非递归实现归并排序 ##释 #代码实现 ##递归实现归并排序 ##原理 是一种基于分治策略的基础排序算法。 1.划分阶段&#xff1a;通过不断递归地将数组从中点处分开&…

迷宫游戏(c++)

我们来玩一个迷宫游戏&#xff0c;尝试走一下面的迷宫。 迷宫游戏 我们用一个二维的字符数组来表示前面画出的迷宫&#xff1a; S**. .... ***T 其中字符S表示起点&#xff0c;字符T表示终点&#xff0c;字符*表示墙壁&#xff0c;字符.表示平地。你需要从S出发走到T&#xf…

【全开源】JAVA共享自习室共享学习室无人系统支持微信小程序+微信公众号+H5

开启智能学习新时代 随着社会的快速发展&#xff0c;人们对于学习环境的需求也日益增加。为满足这一需求&#xff0c;我们推出了“共享自习室系统源码”&#xff0c;旨在通过智能化的管理方式&#xff0c;打造高效、便捷、舒适的共享学习空间。 核心功能 自习室预约&#xf…

6. 网络编程-网络io与select、poll,epoll

https://0voice.com/uiwebsite/html/courses/v13.7.html 首先看看这个学习计划 网络、网络编程、网络原理基础组件&#xff0c;20个。中间件 Redis ,MySQL&#xff0c;Kafka&#xff0c;RPC&#xff0c;Nginx开源框架&#xff08;解决方案&#xff09;业务开发(工程师开发&am…

YOLOv9训练自己的数据集:最新最详细教程

一、代码及论文链接&#xff1a; 代码链接&#xff1a;https://github.com/WongKinYiu/yolov9/tree/main 论文链接&#xff1a;https://arxiv.org/abs/2402.13616 二、使用步骤 1.1 虚拟环境配置 创建一个虚拟环境用于单独对yolov9的环境进行配置&#xff1a; conda crea…

Java中的数组、Set、List、Map类型的互相转换总结

序言 数组、Set、List、Map是Java语言非常常用的几种数据类型&#xff0c;他们之间存在着千丝万缕的联系。关于底层的数据结构我这里就不再多说啦&#xff0c;直接从应用出发&#xff0c;总结他们之间的转换方法&#xff0c;并给出推荐方法。 大家可以点赞收藏等到需要的时候…

传说中的运维门户设计

在IT服务管理这片广阔天地中&#xff0c;运维门户如同一位技艺高超的魔术师&#xff0c;轻轻一挥手&#xff0c;便将纷繁复杂的运维世界化繁为简&#xff0c;编织成一张便捷高效、触手可及的网络。它不仅是ITSM系统中不可或缺的一环&#xff0c;更是连接用户与技术世界的桥梁&a…

【打字】打字训练之针对性键盘区域练习

本文章的核心点是&#xff1a;使用代码生成自己想要训练的键位的词汇&#xff0c;然后导入到打字软件针对性练习 一个程序员突然想纠正打字习惯源于腱鞘炎&#xff0c;虽然使用双拼打字已经不慢了&#xff0c;但是姿势不是很正确&#xff0c;导致了腱鞘炎。 所以想着好好纠正指…

就这?轻轻松松在RK356X Android11适配ML307R Cat.1模组

开源鸿蒙硬件方案领跑者 触觉智能 Industio 本文基于IDO-SXB3568主板&#xff0c;介绍Android11平台上适配中移物联ML307R Cat.1 4G模组的方法。该方法适用于触觉所有RK356X的主板。 IDO-SXB3568是触觉智能推出的RK3568行业主板&#xff0c;预计6月上旬正式上架售卖。该行业主…

Docker安装Mosquitto

在物联网项目中&#xff0c;我们经常用到MQTT协议&#xff0c;用MQTT协议做交互就需要部署一个MQTT服务&#xff0c;而mosquitto是一个常用的MQTT应用服务&#xff0c; Mosquitto是一个实现了消息推送协议MQTT v3.1的开源消息代理软件。MQTT&#xff08;Message Queuing Teleme…

【淘宝超高价女装】电商最好项目:一单赚1000多

课程目录 01.【超高价女装】项目介绍实操案例 02.【超高价女装】找款&#xff1a;配得上1000多的款式 03.【超高价女装】软件上款&#xff1a;600个款为底 04.【超高价女装】标题&#xff1a;能卖1000多的标题 05.【超高价女装】销量布局&#xff1a;主推款做销量评价 06…

【python量化交易】—— Alpha选股策略 - Qteasy自定义交易策略【附源码】

使用qteasy创建并回测Alpha选股交易策略 使用qteasy创建并回测Alpha选股交易策略策略思想第一种自定义策略设置方法&#xff0c;使用持仓数据和选股数据直接生成比例交易信号PS信号&#xff1a;第二种自定义策略设置方法&#xff0c;使用PT交易信号设置持仓目标&#xff1a;第三…

代码审计--变量覆盖

漏洞原理 变量覆盖(Dynamic Variable Evaluation) 是指变量未被初始化&#xff0c; 而我们自定义的变量可以替换程序原有的变量值。 相关函数 $$ &#xff0c; extract &#xff0c; parse_str &#xff0c; import_request_variables 等等 这里涉及到一个安全函数&#xf…

嬴政只比刘邦大三岁,项羽竟是比刘邦小24岁的小老弟?

大秦始皇帝祖龙嬴政、汉太祖高皇帝刘邦、西楚霸王项羽他们的出生顺序怎样&#xff1f; 细看正史我们就知道&#xff0c;项羽嬴政刘邦这三个人&#xff0c;说他们是兄弟可以&#xff0c;说他们有代差也不错&#xff1a;公元前259年&#xff0c;秦始皇降生&#xff0c;三年后的…

Blender 导入资源包的例子

先到清华源下载资源包&#xff1a; Index of /blender/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 具体地址&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/blender/demo/asset-bundles/human-base-meshes/human-base-meshes-bundle-v1.1.0.zip 解压/hum…

【数据结构】C++语言实现二叉树的介绍及堆的实现(详细解读)

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

【Leetcode每日一题】 动态规划 - 简单多状态 dp 问题 - 删除并获得点数(难度⭐⭐)(76)

1. 题目解析 题目链接&#xff1a;LCR 091. 粉刷房子 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 1. 状态定义 在解决这类问题时&#xff0c;我们首先需要根据题目的具体要求来定义状态。针对房屋粉刷问题&#…