每日一练:【优先算法】双指针之复写零(easy)

1. 题目链接:1089. 复写零

2. 题目描述及分析

题目要求我们每遇到一个0,就复写一次,原数组中的元素往后移一位。对于这道题目,我们先忽略掉原地的要求。首先,我们来按照脑海中首先出现的异地的做法,我们通过原数组一指针判断数,另一个指针在新数组中完成对应复写操作。

我们发现大脑中首先出现的异地做法既简单又直接,在没有其他好的方法的情况下,那我们原地操作时是否可以模拟一下这种思路来解决问题呢?

3.算法原理

首先我们试试双指针正向走,但是我们很快发现,由于需要复写0,dest走的比src快,如果正向走,会覆盖掉数组中的非0数,因此正向走是行不通的。

既然dest走到比src快,那我们是否可以让dest先走呢?

我们观察题目,发现由于会复写0,新数组中的最后一个数在原数组中并不是最后一个数。这就意味着原数组中后几个数是可以抛弃的。我们上面提到由于dest与src走的速度不一致,我们需要让src先走,所以既然数组后面的几个数据可以抛弃,那么我们就让双指针从后往前开始走。

通过上图,我们知道我们的方法已经成功了,但是问题有回来了,为什么src指向的值是新数组中最后一个数呢?我们如何找到这个数呢?

我们回看我们一开始同向原地的操作,我们发现dest走快会导致覆盖原来的数据,但是如果我们不同过dest修改数组,我们发现dest与src走的流程是,跟异地的操作一摸一样的,这样当我们dest走到结尾,src指向的数据就是原地修改后数组的最后一个位置。

注:我们会遇到下图中的情况,模拟后dest会越界,这个需要我们手动仿照模拟的过程处理相关的值,并将dest移动到正确位置。

4.算法代码

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--;
            }
        }
    }
};
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZLRRLZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值