算法训练篇02--力扣1089.复写零

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

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]

示例 2:

输入:arr = [1,2,3]
输出:[1,2,3]
解释:调用函数后,输入的数组将被修改为:[1,2,3]

3.解法(原地复写 - 双指针)

算法思路:

如果从前向后进行原地复写操作的话,会导致没有复写的数被覆盖掉。因此我们选择从后往前的复写策略。

但是从后往前复写的时候,我们需要找到最后一个复写的数,因此我们的大题流程分两步:

  1. 从前向后,寻找最后一个复写的数
  2. 从后向前,进行复写操作                 

算法流程:

  1. 初始化两个指针:cur = 0,dest = -1
  2. 找到最后一个复写的数:                                                                                                    当cur < n的时候,一直执行下面的循环:                                                                    判断cur的元素,如果cur的元素为0,则dest += 2;如果cur的元素不为0,则dest++。  判断dest是否>=n-1,如果dest>=n-1则break跳出循环,此时cur找到最后一个复写的数;反之dest<n-1,则cur++;
  3. 判断dest是否越界:                                                                                                         如果dest == n,则dest越界。令n-1位置为0,dest -= 2,cur--;                                   如果dest == n-1,则无需有任何操作。
  4. 从后向前,进行复写:判断cur位置的值                                                                           a.如果cur位置的值为0,则dest,dest--的位置修改成0,dest -= 2;                             b.如果cur位置的值不为0,则dest位置修改成cur位置的值,dest-- ;                             c.cur--。继续复写下一个数  

4.C++算法代码

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int cur = 0, dest = -1,n = arr.size();
       while(cur<n)
       {
        if(arr[cur] == 0)
        {
            dest += 2;
        }
        else
        {
            dest++;
        }
        if(dest >= n-1)
        break;
        cur++;
       }

        if(dest == n)
        {
            arr[n-1] = 0;
            dest -= 2;
            cur--;
        }

        while(cur>=0)
        {
            if(arr[cur] != 0)
            {
                arr[dest] = arr[cur];
                dest--;
            }
            else
            {
                arr[dest] = arr[dest-1] = 0;
                dest-=2;
            }
            cur--;
        }
    }
};

      评论 1
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

      当前余额3.43前往充值 >
      需支付:10.00
      成就一亿技术人!
      领取后你会自动成为博主和红包主的粉丝 规则
      hope_wisdom
      发出的红包
      实付
      使用余额支付
      点击重新获取
      扫码支付
      钱包余额 0

      抵扣说明:

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

      余额充值