题目要求我们每遇到一个0,就复写一次,原数组中的元素往后移一位。对于这道题目,我们先忽略掉原地的要求。首先,我们来按照脑海中首先出现的异地的做法,我们通过原数组一指针判断数,另一个指针在新数组中完成对应复写操作。
我们发现大脑中首先出现的异地做法既简单又直接,在没有其他好的方法的情况下,那我们原地操作时是否可以模拟一下这种思路来解决问题呢?
首先我们试试双指针正向走,但是我们很快发现,由于需要复写0,dest走的比src快,如果正向走,会覆盖掉数组中的非0数,因此正向走是行不通的。
既然dest走到比src快,那我们是否可以让dest先走呢?
我们观察题目,发现由于会复写0,新数组中的最后一个数在原数组中并不是最后一个数。这就意味着原数组中后几个数是可以抛弃的。我们上面提到由于dest与src走的速度不一致,我们需要让src先走,所以既然数组后面的几个数据可以抛弃,那么我们就让双指针从后往前开始走。
通过上图,我们知道我们的方法已经成功了,但是问题有回来了,为什么src指向的值是新数组中最后一个数呢?我们如何找到这个数呢?
我们回看我们一开始同向原地的操作,我们发现dest走快会导致覆盖原来的数据,但是如果我们不同过dest修改数组,我们发现dest与src走的流程是,跟异地的操作一摸一样的,这样当我们dest走到结尾,src指向的数据就是原地修改后数组的最后一个位置。
注:我们会遇到下图中的情况,模拟后dest会越界,这个需要我们手动仿照模拟的过程处理相关的值,并将dest移动到正确位置。
class Solution {
public:
void duplicateZeros(vector<int>& arr) {
int cur = 0,dest = -1,n = arr.size();
while(cur < n)
{
if(arr[cur])
{
dest++;
}
else
{
dest += 2;
}
if(dest >= n - 1)
{
break;
}
cur++;
}
if(dest >= n)
{
arr[n - 1] = 0;
dest -= 2;
cur--;
}
while(cur >= 0)
{
if(arr[cur])
{
arr[dest--] = arr[cur--];
}
else
{
arr[dest--] = 0;
arr[dest--] = 0;
cur--;
}
}
}
};
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有