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

双指针---《复写零》

目录

题目描述 

题目讲解

算法原理

先打预防针(异地操作)

原理讲解

总结

 代码展示

真正开始(就地操作)

就地操作遇见的问题

从前往后操作

解决办法

特殊的从后往前操作

如何确定cur的位置?

总结  

 代码展示


💫只有认知的突破💫才来带来真正的成长💫编程技术的学习💫没有捷径💫一起加油💫

           🍁感谢各位的观看🍁欢迎大家留言🍁咱们一起加油🍁努力成为更好的自己🍁

题目描述 

题目:复写零

如图所示的题目描述:

题目讲解

本题目要求的是,对于0元素要进行复写,也就是写2遍,其余元素向后移动,如示例1所示的结果。注意:不允许开辟新的数组,只能就地操作原数组。

算法原理

先打预防针(异地操作)

我们要先有一个思想的过渡期,我们先不考虑就地操作,先考虑异地操作,也就是说先建立一个新数组。

原理讲解

我们先创建一个和原数组空间一样大的新数组num,然后我们定一个指向新数组首元素的指针begin_num如图所示:

同时e依次遍历原数组,当为非0元素时,就插入begin_num指向的空间,然后两者同时向后走一步 - -。当遇到0元素时,就对0元素进行复写,然后两者同时向后走一步- -。当新数组num走到末尾就结束程序。然后再把新数组的数据赋值拷贝给原数组。

总结

1.先创建一个和原数组大小一样的新数组

2.创建一个指向新数组首元素的指针

3.当e指向的元素非0时,就直接拷贝到begin_num指向的空间,然后两者同时向后走一步

4.当e指向的元素为0时,begin_num就直接复写两遍0,复写完之后,两者同时向后走一步

5.把新数组num的数据赋值拷贝给原数组

 代码展示

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
       vector<int>num(arr.size(),1);        //创建一个同样大小空间的新数组
        auto begin_num=num.begin();        //指向新数组首元素的指针
       for(auto&e:arr)
        {
              if(e)        //处理非0元素
               {
                  *begin_num=e;
                   begin_num++;
                }
               else        //处理0元素
                {
                    num[begin_num++]=0;        //进行复写操作
                    num[begin_num++]=0;
                }
               if(begin_num==num.end())    //结束条件由num决定,当begin_num等于num.end()就结束循环
                break;
        } 
        arr=num;        //再把新数组的元素拷贝给原数组
    }
};

真正开始(就地操作)

就地操作遇见的问题

从前往后操作

当我们把异地操作合一起时,就可以用两个指针指向本地数组。我们就定两个指针,cur和dst。cur用来遍历数组,dst用来存储非0元素和0元素。如图所示:

当我们按照异地原理进行操作的时候,这个时候就会出现一个大大的问题前两个数据还能正常的插入,但越往后操作就会发现,这样操作下去就会使后面的所有数据都为0,这明显不对了

解决办法

特殊的从后往前操作

我们从前往后操作行不通,那么我们就从后往前进行操作。当然,我们这里从后往前操作不是两个指针都指向同一个数据,这样的话,就会导致前面的所有数据都为0我们可以观察一下原数组和复写之后的数组,可以让cur指针,指向复写之后的数组的最后一个位置数据,让dst指针指向数组的最后一个位置,因为cur指向的数据是复写数组最后一个数据,肯定是要放在dst指向的位置的,dst就是用来接收cur的数据和进行复写操作的。如图所示:

然后再按照异地的操作原理,就可以完美的解决了。接下来就是解决——如何精确的找到cur的位置呢?dst不用找,它必定指向数组的最后一个位置。关键就是找到cur的位置,因为并不能确定复写数组的最后一个元素是哪个。

如何确定cur的位置?

我们可以从前往后的进行查找cur的位置。让cur指向数组的首元素,即cur=0,让dst指向数组的前面位置,即dst=-1,如图所示:

当遇到非0元素时,dst就往前走一步,然后cur也往前走一步。当遇到0元素时,dst就往前走两步,然后cur往前走一步。结束条件就是dst<n。按照这个方法,就可以完美的找到两个指针该对应的位置,然后就按照异地的原理进行操作,就可以解决了。这种找位置的方法,是完全没问题的。但是在按照异地原理操作的时候,要特殊处理一种情况。比如数据:1,0,3,0,4。我们按照方法找到cur和dst的位置,如图所示:

对于这个例子,我已经找到了各自对应的位置。会发现,dst已经越界了,当我们从dst位置进行复写时,就会发生越界的数据访问,这不代表方法是错误的,这俩指针都正确的指向了各自的位置只不过,我们在进行复写操作的时候,这种情况要特殊处理而且这种情况的出现,也就只有最后一个复写数据为0时才会出现。所以我们进行复写时, 要在[n-1]的位置开始复写,同时dst要往前走两步,然后cur也往前走一步。后面就是正常的复写操作了。   

总结  

1.先从前往后确定cur和dst的位置

2.cur指向数组的首元素位置,dst指向数组之前的位置

3.非0数据,dst就++,然后,cur++。0数据时,dst要走两步,然后cur++,dst<n结束条件

        3.1:当要复写的位置为数据0时,这个时候dst也越界了。在进行复写操作的时候,先进行[n-1]的位置为0,然后dst往前走两步,cur往前走一步。

4.正常进行复写操作

 代码展示

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int cur=0,dst=-1,n=arr.size();        //确认cur和dst的起始位置
        while(cur<n)        //确定cur和dst的复写位置
        {
            if(arr[cur])dst++;        //非0数据走一步
            else dst+=2;            //0数据走两步
            if(dst>=n-1)break;    //结束条件
            cur++;
        }
        if(dst==n)        //处理特殊情况
        {
            arr[--dst]=0;
            cur--;
            dst--;
        }
        
         while(cur>=0)        //正常的异地的复写操作
        {
            if(arr[cur])
                swap(arr[cur--],arr[dst--]);
            else
            {
                arr[dst--]=0;
                arr[dst--]=0;
                cur--;
            }
         }
        
    }
};

相关文章:

  • 使用keepalived结合tomcat和nginx搭建三主热备架构
  • 【零基础学python】python高级语法(四)
  • Java 大视界 -- Java 大数据在智能政务数字身份认证与数据安全共享中的应用(156)
  • Flutter TabBar 右侧渐变遮罩实现中的事件处理问题
  • LeetCode热题100|128.最长连续序列,283.移动零
  • unity 做一个圆形分比图
  • RAG技术的进化:RQ-RAG查询优化/化繁为简Adaptive-RAG智能分类/精准出击
  • 力扣HOT100之普通数组:189. 轮转数组
  • 算法250327题目
  • C语言 —— 此去经年梦浪荡魂音 - 深入理解指针(卷五)
  • 如何快速对比两个不同的excel文件中的单元格的数据是否完全相同 并把不同的单元格的背景颜色更改为红色?
  • MySQL索引优化与应用指南
  • 【电子通识】铅笔硬度简史:从石墨到工业标准
  • 香港QILSTE/旗光 H6-108QLB高亮LED灯珠
  • AnimateCC技术教学:使用后台JavaScript修改ballObj实例的填充色为径向渐变色-由DeepSeek产生
  • 【踩坑系列】使用httpclient调用第三方接口返回javax.net.ssl.SSLHandshakeException异常
  • 【位运算】268. 丢失的数字
  • 深度讨论Python for循环
  • SQL Server安装过程中提示 .NET Framework 4.8 缺失
  • 【cocos creator 3.x】3Dui创建,模型遮挡ui效果
  • 平台推广网站排名/优化网站seo方案
  • 网站流量100g/软文发布平台与板块
  • wordpress的文章多重筛选/kj6699的seo综合查询
  • 石家庄网站设计公司/营销自动化工具
  • 创业做招商加盟类网站赚钱/开发网站建设公司
  • 西宁做网站需要多少钱/最佳搜索引擎磁力