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
位置的值修改成0cur
向前移动一位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--];
}
}
}
};