双指针_复写零_C++


1. 题目解析


leetcode链接:https://leetcode.cn/problems/duplicate-zeros/

给你一个长度固定的整数数组 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]

2. 算法解析


先根据“异地”操作,然后优化成双指针下的“就地”操作

1. 异地操作:

  • cur指向原数组,dest指向新数组,他们的起始位置如下。

在这里插入图片描述

  • cur当前指向的值为1,让dest++,拷贝1,然后让cur++

在这里插入图片描述

  • 此时cur位置值为0,让dest向后移动两格,拷贝两次0,然后让cur++

在这里插入图片描述

  • 以此类推,cur位置不为0,就拷贝1次,为0,就拷贝两次,直到dest越界。

在这里插入图片描述

2. 优化为“就地”操作

  • curdest的初始位置如下。

在这里插入图片描述

  • cur位置不为0,dest就向后移动1格,为0就向后移动两格。此时肯定不能从左向右复写0,因为这会覆盖到有效数据2,只能先找到复写0后的最后一个位置,然后从右向左复写0。
  • 得到最后一个位置时,指针状态如下。

在这里插入图片描述

  • 然后从右向左覆盖。

在这里插入图片描述

  • 找最后一个位置时,有可能出现如下情况,dest越界。这种情况出现的原因,是因为cur指向的最后一个位置是0。需要特殊处理。

在这里插入图片描述

  • 相当于,此时cur位置的0只能复写一次,因为没有位置了。

在这里插入图片描述


3. 代码实现


class Solution {
public:
    void duplicateZeros(vector<int>& arr) 
    {
        // 1.先找到最后一个数
        int dest = -1;
        int cur = 0;
        int n = arr.size();

        while(cur < n)
        {
            if(arr[cur])        // 非零元素,dest+1
                dest++;
            else                // 零元素,dest+2
                dest+=2;            
            if(dest >= n - 1) break;    // 如果dest超出数组范围,就break掉
            cur++;
        }

        // 2.处理边界情况,0只复写一次
        if(dest == n)
        {
            arr[dest - 1] = 0;
            cur--;
            dest-=2;
        }

        // 3.从后向前,完成复写操作
        while(dest != cur)
        {
            if(arr[cur])
                arr[dest--] = arr[cur--];
            else
            {
                arr[dest--] = 0;
                arr[dest--] = 0;
                cur--;
            }
        }
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

-指短琴长-

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

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

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

打赏作者

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

抵扣说明:

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

余额充值