当前位置: 首页 > news >正文

每日一题:LeetCode-1089. 复写零

每日一题系列(day 09)

前言:

🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈

   🔎🔎如果说代码有灵魂,那么它的灵魂一定是👉👉算法👈👈,因此,想要写出💚优美的程序💚,核心算法是必不可少的,少年,你渴望力量吗😆😆,想掌握程序的灵魂吗❓❗️那么就必须踏上这样一条漫长的道路🏇🏇,我们要做的,就是斩妖除魔💥💥,打怪升级!💪💪当然切记不可😈走火入魔😈,每日打怪,拾取经验,终能成圣🙏🙏!开启我们今天的斩妖之旅吧!✈️✈️


题目:

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

示例:

在这里插入图片描述

提示:

  • 1 <= arr.length <= 104
  • 0 <= arr[i] <= 9

思路:

  如果自己尝试写的时候发现其实并不简单,虽然被力扣标为简单。题目说遇到0要复写,把0后面的元素全部向后移动一位,留下一个位置给复写的0,而且只能在本数组内操作,不能扩容。在上到题目中我们说了,这种类似的问题都是可以使用双指针来解决。如何使用双指针就成了问题。

  虽然这题是让我们在原数组操作,但是我们不妨先开辟一个数组,cur指针指向原数组,dest指针指向新数组,只要cur不为0,dest就复制cur的值,如果cur为0,dest就移动两步,且每一步都写为0。

在这里插入图片描述

  这个时候我们发现dest指针所在数组与测试用例的结果相同,说明我们的思路是正确的,但是题目要求我们是原地操作。

  首如果我们按照常规的思路,首先设置cur指针用来遍历数组,同时表示dest指针走几步,因为开始不知道dest走几步,所以将dest的值设置为-1。

在这里插入图片描述

  既然我们从左向右的双指针不得行,我们可以考虑从右向左来进行复写操作,但是我们要想保证复写的正确性,还需要知道正向复写最后一个复写的元素,这样才能从后向前复写。
  其实我们在最开始假设有新数组来复写的操作,我们可以看到最后一个复写的值为4,最后dest和cur又都多走了一步,我们仅需将条件控制为:

dest <= arr.size() - 1;

即可,这样cur就会指向最后一个需要复写的元素了,dest也正好指向最后一个元素。而对于原地操作,我们仅仅需要找到cur的位置和dest的位置就行,所以在找位置的情况我们不需要复写,就可以在同一个数组操作了。

在这里插入图片描述

  这个时候,我们的cur的位置就是最后需要复写的位置,而dest正是我们需要复写的最后一个元素。
  找到这个元素之后,我们就可进行从后往前的复写操作了,当arr[cur]不为0的时候,dest向前移动一位并且复写这个数,cur–。如果cur为0,dest就向前走两位,每位复写为0,cur–。即可

代码实现:

class Solution {
public:void duplicateZeros(vector<int>& arr) {int cur = 0;int dest = -1;while(cur < arr.size()){if(arr[cur]) dest++;elsedest += 2;if(dest >= arr.size() - 1) break;cur++;}while(dest > -1){if(arr[cur]) arr[dest--] = arr[cur--];//cur不为0拷贝一次else {arr[dest--] = 0;//cur为0复写两次arr[dest--] = 0;cur--;}}}
};

但是这个时候我们运行的时候却发现:

在这里插入图片描述
出现了这么的错误,我们可以看到他给我们的报错的测试用例:

在这里插入图片描述
  我们不妨画图看一下问题在哪?

在这里插入图片描述
  原来是我们的dest指针越界了,在我们复写的时候这种情况会在数组外边越界访问了,这种情况是造成的原因是最后一个复写元素为0的原因。
  如果不考虑越界的情况继续复写一步操作我们会发现:

在这里插入图片描述
  所以其实我们仅仅需要控制住边界条件,复写时将:

arr[arr.size() - 1] = 0;

即可。所以我们可以这样改:

代码实现:

class Solution {
public:void duplicateZeros(vector<int>& arr) {int cur = 0;int dest = -1;while(cur < arr.size()){if(arr[cur]) dest++;elsedest += 2;if(dest >= arr.size() - 1) break;cur++;}if(dest == arr.size())//加上边界判断即可{arr[arr.size() - 1] = 0;dest -= 2;cur--;}while(dest > -1){if(arr[cur]) arr[dest--] = arr[cur--];else {arr[dest--] = 0;arr[dest--] = 0;cur--;}}}
};

在这里插入图片描述


  这样我们就可以通过了,这题虽然被标记为简单,但是我感觉却一点也不简单(主要是太菜),需要注意的是双指针的灵活运用,以及边界情况的考量要到位。

相关文章:

  • RabbitMQ学习一
  • 解读《陆奇最新演讲实录—我的大模型世界观》
  • Linux中的Swap和Mem:有什么区别?
  • ubuntu22.04识别CH340的问题汇总
  • 蓝桥杯-02-蓝桥杯C/C++组考点与14届真题
  • 240. 搜索二维矩阵 II -- 力扣 --JAVA
  • 【高效开发工具系列】PlantUML入门使用
  • 6.Spring源码解析-loadBeanDefinitions(String location)
  • 利用Python爬虫爬取豆瓣电影排名信息
  • Unity 注释的方法
  • Android 获取应用签名
  • 32/64位系统下使用ATT风格汇编调用c函数
  • C语言--每日选择题--Day31
  • 使用yolov7进行多图像视频识别
  • 使用Docker Compose搭建CIG监控平台
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • chrome扩展demo1-小时钟
  • golang 发送GET和POST示例
  • Java 多线程编程之:notify 和 wait 用法
  • java 多线程基础, 我觉得还是有必要看看的
  • javascript数组去重/查找/插入/删除
  • Service Worker
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • Tornado学习笔记(1)
  • 从0实现一个tiny react(三)生命周期
  • 近期前端发展计划
  • 如何设计一个比特币钱包服务
  • 如何用Ubuntu和Xen来设置Kubernetes?
  • 转载:[译] 内容加速黑科技趣谈
  • 扩展资源服务器解决oauth2 性能瓶颈
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • # 安徽锐锋科技IDMS系统简介
  • #if #elif #endif
  • #我与Java虚拟机的故事#连载04:一本让自己没面子的书
  • (07)Hive——窗口函数详解
  • (C)一些题4
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (四)JPA - JQPL 实现增删改查
  • (四)库存超卖案例实战——优化redis分布式锁
  • . Flume面试题
  • ... fatal error LINK1120:1个无法解析的外部命令 的解决办法
  • .NET Core 中的路径问题
  • .NET HttpWebRequest、WebClient、HttpClient
  • .Net 知识杂记
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
  • .net6 webapi log4net完整配置使用流程
  • .net流程开发平台的一些难点(1)
  • []Telit UC864E 拨号上网
  • [2018][note]用于超快偏振开关和动态光束分裂的all-optical有源THz超表——
  • [2019.2.28]BZOJ4033 [HAOI2015]树上染色
  • [android] 切换界面的通用处理
  • [Android]使用Git将项目提交到GitHub
  • [C语言]——柔性数组