1.题目链接:复写零
2.题目描述
给你⼀个⻓度固定的整数数组
arr,请你将该数组中出现的每个零都复写⼀遍,并将其余的元素
向右平移。
注意:请不要在超过该数组⻓度的位置写⼊元素。请对输⼊的数组就地进⾏上述修改,不要从函数返
回任何东西。
⽰例1:
输⼊:arr = [1,0,2,3,0,4,5,0]
输出:[1,0,0,2,3,0,0,4]
解释:
调⽤函数后,输⼊的数组将被修改为:[1,0,0,2,3,0,0,4]
3.算法思路
- 如果从前往后进行原地复写操作的话,由于0的出现会复写两次,导致没有复写的数被覆盖掉,因此我们选择用从后往前的思路
- 从后往前不能直接找,需要先找到最后一个复写的数(先找到最后一个单写的数,然后从后向前进行复写操作)
4.算法流程
- 初始化两个指针cur=0,dest=-1;
- 找到最后一个复写的数: 
  - 找到最后一个复写的数: 
    - 当cur<n的时候,一直执行下面循环- 判断cur位置的元素:(如果是0的话,dest往后移动两位;否则,dest往后移动一位)
 
- 判断
- 判断dest是否已经到结束位置,如果结束就终止循环
- 如果没有cur++,继续判断
 
- 当
 
- 找到最后一个复写的数: 
    
- 判断dest是否越界到n的位置- 如果越界,执行下面三步: 
    - n-1位置的值修改成0
- cur向前移动一位
- dest向前移动两步
 
 
- 如果越界,执行下面三步: 
    
- 从cur位置开始往前遍历原数字,依次还原处复写后的结果数组: 
  - 判断cur位置的值 
    - 如果是0:dest以及dest-1位置修改成0,dest-=2;
- 如果非零:dest位置修改成cur指向的元素,dest-=1
 
- 如果是0:dest以及
- cur--,复写下一步位置
 
- 判断cur位置的值 
    
5.算法流程图
5.1找到最后一个需要的元素

5.2找到最后一个需要复写的数(特殊情况)

5.3完成复写操作

6.C++代码实现
class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int n=arr.size();
        int cur=0;
        int dest=-1;
        while(cur<n)
        {
            if(arr[cur])
            {
                ++dest;
            }
            else
            dest+=2;
            if(dest>=n-1)
            {
                break;
            }
            cur++;
        }
        if(dest==n)
        {
            arr[n-1]=0;
            cur--;
            dest-=2;
        }
        while(cur>=0)
        {
            if(arr[cur]==0)
            {
                arr[dest--]=0;
                arr[dest--]=0;
                cur--;
            }
            else
            {
                arr[dest--]=arr[cur--];
            }
            
        }
    }
};








![[资源推荐] 复旦大学张奇老师科研分享](https://img-blog.csdnimg.cn/9b8643c952f04c0b9e5b366ea29c03fb.png)










