一. 题目描述

二. 解题思路
这种题对下标的掌控极易出错,所以一定要画图,掌握边界情况。
1)首先大思路上我们用的是双指针,一个cur指针遍历数组,另一个dest指针修改数组、复写零。
2)因为要求就地修改,所以一定不能从前往后遍历修改,否则只要出现一个被复写的零就会覆盖下一个值,这很容易看出来。
3)既然不能从前往后,我们可以从后往前。

三. 代码实现
cpp
class Solution
{
public:
void duplicateZeros(vector<int>& arr)
{
int cur = -1, dest = -1;
// arr.size()返回size_t类型,与int类型的dest比较时发生类型提升
// int->size_t,-1->无符号整型的最大值,不会进入第一个循环
// 所以拿出来隐式类型转换一下
int n = arr.size()-1;
// 1. 遍历找到正常复写结束时,cur和dest的位置
while(dest < n)
{
cur++;
if(arr[cur] != 0) dest += 1;
else dest += 2;
}
// 如果倒数第二个数是0,dest会到arr.size()的位置
// 此时如果直接执行arr[dest] = 0;属于越界访问,先处理一下
if (dest > n)
{
dest--;
arr[dest--] = 0;
cur--;
}
// 从后往前复写
while(cur >= 0)
{
if(arr[cur] != 0) arr[dest--] = arr[cur--];
else
{
arr[dest] = 0;
arr[dest-1] = 0;
dest -= 2;
cur--;
}
}
}
};