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

双指针算法专题之——复写零

文章目录

  • 题目介绍
  • 思路分析
    • 异地复写
    • 优化为就地复写
  • AC代码

题目介绍

链接: 1089. 复写零

在这里插入图片描述

思路分析

那么这道题我们依然可以使用双指针算法来解决

异地复写

先不考虑题目的要求,直接就地在原数组上修改,可能不太好想,我们这里可以先在一个新开的数组上进行复写

起始双指针分别指向两个数组0下标在这里插入图片描述
如果cur指向的元素是非0,dest只把cur的值拷贝下来,无需复写(只有0才复写),然后两者都++
在这里插入图片描述
cur如果指向0,那dest要拷贝两次(复写一次),然后两者都++
在这里插入图片描述
后续也是如此
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
其实很简单,就是模拟题目要求的复写操作,非0不动,0复写
对比一下题目的例子,结果是正确的
在这里插入图片描述

优化为就地复写

那接下来我们就要尝试在上面的基础上进行优化,优化为原地复写
怎么做呢?现在就只能在原数组上就地操作了

我们来尝试一下:

在这里插入图片描述
上来cur指向非0
无需任何操作,两者++即可,刚才我们要拷贝是因为dest指向一个新数组,现在都指向原数组
在这里插入图片描述
然后cur是0,所以要复写一次0
在这里插入图片描述
那就变成这样了。
这样其实已经不行了,因为2被复写的0覆盖掉了,而cur++之后又指向了刚刚复写的0,这样后面都是0了,肯定的不对的

所以这道题从前向后移动指针是不行的,那我们可以反过来看看!

从后向前呢?
在这里插入图片描述
那两个指针都指向最后一个元素吗?
🆗,dest呢从最后一个位置开始,而cur,我们让它一开始指向最后一个被处理的数。
因为最后一个被处理的数处理完毕一定是在数组最后一个位置的。
怎么找最后一个处理的数我们后面说,但是对于当前这个例子,我们知道最后一个处理的数,就是4
在这里插入图片描述
然后,就让它们从后往前移动,进行像上面异地复写一样的操作就行了
在这里插入图片描述
答案正确!

总结一下:

先找到最后一个被处理的数,然后从后往前进行复写即可

那现在关键问题在于,对于任意一个数组,我们如何找到它最后一个处理的元素是谁?

那么这个问题也可以使用双指针来解决!
怎么做呢?
依然用上面这个例子
在这里插入图片描述
让cur从0开始,dest从-1开始,然后,其实就是去模拟整个复写的过程。
如果cur指向的是非0,让dest走一步(只拷贝,不复写),然后cur++;
如果是0,则dest走两步(拷贝+复写),然后cur++
当dest走到最后一个位置时候,就结束了,再走就越界了,此时,cur指向的元素就是最后一个被处理的数。
这个我就不再画图了,大家如果不理解可以自己画一下图走一遍。

但是,还有一种情况需要考虑:

在这里插入图片描述
如果最后一个被处理的数是0,这时dest往后走两步有可能出现越界的情况。
所以,针对这种情况,我们可以处理一下:
此时0就是最后一个被处理的数,cur从0开始倒着处理,那此时dest应该拷贝+复写,然后两者都- -
但是此时dest是越界的,即执行拷贝的位置是越界的,所以cur直接- -,然后复写一个0,然后两者都- -。
即把n-1下标置0,cur- -,dest-=2。
后续正常处理就行。

AC代码

上面分析的比较清楚了,代码就不过多解释了
在这里插入图片描述
在这里插入图片描述

class Solution {
public:void duplicateZeros(vector<int>& arr) {int n = arr.size();// 1.先找到最后一个被处理的元素int cur = 0;int dest = -1;while (dest < n - 1) {if (arr[cur] != 0)dest++;elsedest += 2;if (dest >= n - 1)break; // 如果dest>=n-1(走到最后一个位置或者越界的情况),// 此时cur就是最后一个被处理的元素,不能再++了,直接breakcur++;}// 2.处理一下dest越界的情况if (dest == n) {arr[n - 1] = 0;cur--;dest -= 2;}// 3.从后往前进行复写while (dest >= 0) {if (arr[cur] != 0)arr[dest] = arr[cur];else {arr[dest] = 0;arr[--dest] = 0;}cur--;dest--;}}
};

http://www.mrgr.cn/news/94334.html

相关文章:

  • 记录一个SQL自动执行的html页面
  • 求递增子序列LIS的两种方法
  • 深度学习正则化技术之权重衰减法、暂退法(通俗易懂版)
  • LangChain+InternLM2搭建知识库
  • 条款1:理解模版性别推导
  • Kubernetes教程(九)了解卷volume的emptyDir和hostPath
  • 将串口接收到的十六进制数据转为十进制
  • ⭐算法OJ⭐汉明距离【位操作】(C++ 实现)Hamming Distance
  • 【vue + JS】OCR图片识别、文字识别
  • 《基于大数据的营养果蔬推荐系统的设计与实现》开题报告
  • 在 Windows 上快速部署 OpenManus:从安装到运行
  • 计算机网络——DHCP实验
  • python -面试题--算法
  • RGV调度算法(三)--遗传算法
  • LeetCode 解题思路 15(Hot 100)
  • 独立开发记录:使用Trae和Cloudflare快速搭建了自己的个人博客
  • ES6回顾:闭包->(优点:实现工厂函数、记忆化和异步实现)、(应用场景:Promise的then与catch的回调、async/await、柯里化函数)
  • 【C#学习笔记04】C语言格式化输出
  • 深度剖析 Doris 数据倾斜,优化方案一网打尽
  • 【二分查找 寻找首端】P3718 [AHOI2017初中组] alter|普及+