1089. Duplicate Zeros

Given a fixed length array arr of integers, duplicate each occurrence of zero, shifting the remaining elements to the right.

Note that elements beyond the length of the original array are not written.

Do the above modifications to the input array in place, do not return anything from your function.

Example 1:

Input: [1,0,2,3,0,4,5,0]
Output: null
Explanation: After calling your function, the input array is modified to: [1,0,0,2,3,0,0,4]

Example 2:

Input: [1,2,3]
Output: null
Explanation: After calling your function, the input array is modified to: [1,2,3]

Note:

  1. 1 <= arr.length <= 10000
  2. 0 <= arr[i] <= 9

这道题给了一个数字数组,让将每个0都复制一个,然后将数字右移一位,数组的长度还是保持不变,右移出范围的数字就移除掉。这不是一道难题,比较直接的做法就是新建一个结果数组 res,然后遍历给定数组 arr,for 循环条件加上一个 res 的长度小于n,将当前遍历到的数字加入 res,然后判断若当前数字是0,且此时 res 长度小于n,则再加个0到 res 中,最后把 arr 更新为 res 即可,参见代码如下:

解法一:

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int n = arr.size();
        vector<int> res;
        for (int i = 0; i < n && res.size() < n; ++i) {
            res.push_back(arr[i]);
            if (arr[i] == 0 && res.size() < n) res.push_back(0);
        }
        arr = res;
    }
};

再来看一种双指针的解法,这里还是用了一个额外数组 vec,初始时复制 arr 数组。用两个指针i和j分别指向 arr 和 vec 数组,进行 while 循环,条件是i小于n,首先将 vec[j] 赋值给 arr[i],然后判断若 arr[i] 是0,且 i+1 小于n,则i自增1后,将 arr[i] 赋值为0,然后i和j分别自增1,参见代码如下:

解法二:

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
    vector<int> vec = arr;
        int i = 0, j = 0, n = arr.size();
        while (i < n) {
            arr[i] = vec[j];
            if (arr[i] == 0 && i + 1 < n) arr[++i] = 0;
            ++i; ++j;
        }
    }
};

下面来看一种不使用额外空间的解法,还是使用了双指针来做,j初始化为 arr 数组的长度加上其中0的个数,实际上就是在不右移的情况下得到的新的数组的长度,i从 n-1 开始遍历到0,首先对j进行自减1,若此时j小于n了,说明已经到需要更新的地方了,将 arr[j] 赋值为 arr[i],接下来处理0的情况,若 arr[i] 为0,且自减1后的j小于n,则将 arr[j] 赋值为0,还是不太理解整个过程的童鞋可以将例子1带入,一步一步来尝试运行,其实并不是很难理解,参见代码如下:

解法三:

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int n = arr.size(), j = n + count(arr.begin(), arr.end(), 0);
        for (int i = n - 1; i >= 0; --i) {
            if (--j < n) arr[j] = arr[i];
            if (arr[i] == 0 && --j < n) arr[j] = 0;
        }
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/1089

参考资料:

https://leetcode.com/problems/duplicate-zeros/

https://leetcode.com/problems/duplicate-zeros/discuss/312743/JavaC%2B%2B-O(n)-or-O(1)

https://leetcode.com/problems/duplicate-zeros/discuss/312727/C%2B%2BJava-Two-Pointers-Space-O(1)

LeetCode All in One 题目讲解汇总(持续更新中…)


转载请注明来源于 Grandyang 的博客 (grandyang.com),欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 grandyang@qq.com

💰


微信打赏


Venmo 打赏

(欢迎加入博主的知识星球,博主将及时答疑解惑,并分享刷题经验与总结,试运营期间前五十位可享受半价优惠~)

×

Help us with donation