「小白leetcode刷题之路🚀(三)」 Duplicate Zeros

1,002 阅读2分钟

给定一个固定长度的整数数组arr,每次出现0时,将剩余的元素向右移动,超过原始数组长度的元素不会被写入。

事例1:

输入: [1,0,2,3,0,4,5,0]
输出: null
解释: 你的函数调用之后,输入的数组被修改成: [1,0,0,2,3,0,0,4]

事例2:

输入: [1,2,3]
输出: null
解释: 你的函数调用之后,输入的数组被修改成: [1,2,3]

注意⚠️:

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

leetcode传送门: leetcode.com/problems/du…


解题

step1:先看看怎么移动数组中的元素

先用人的思维想一想怎么移动数组里的元素:有一个数组[1,2,3,4],从0开始往后移动,将下标为0的移动到下标为1的位置上,下标为1的移动到下标为2的位置上,依次类推。。。这样就完成数组的移动啦,最后我们可以得到这样的结果:[1,1,2,3],对吧,人的思维这样想起来好像一切都很完美,让我们把上面这段想法付诸实践,用程序写出来:

public class DuplicateZeros {

    public static void main(String[] args) {
        int[] arr = new int[]{1,2,3,4};

        int i = 0;
        while (i < arr.length - 1){
            arr[i+1] = arr[i];
            i++;
        }

        System.out.println(Arrays.toString(arr));
    }
}

output: [1, 1, 1, 1]

哎?好像输出的结果不对,为什么会这样呢?稍微有点编程基础的应该都知道,不过我还是来画个图解释一下吧~

原来是在程序执行的过程中前面的值把后面的覆盖掉了,emmmm,开动大脑好好想想,可不可以一开始就从元素值为3的位置移动呢(数组的capacity就只有4个,从最后一个下标往后移动,就没地方放了)?这样就可以避免前面的值覆盖后面的。

这次让我们先画图将意思表达出来,然后再来写程序吧~~

程序如下:

public class DuplicateZeros {

    public static void main(String[] args) {
        int[] arr = new int[]{1, 2, 3, 4};

        int i = arr.length - 1;
        while (i > 0) {
            arr[i] = arr[i-1];
            i--;
        }

        System.out.println(Arrays.toString(arr));
    }
}

output:[1, 1, 2, 3]

step2: 大胆猜想一下解法

学会了怎么移动数组后就简单啦,下面说说我的思路:

  • 算出数组中0的个数,数组中元素的长度 + 元素0的个数 = 要移动的步长
  • 将步长参与计算,遇到0就多走一步
  • 因为是固定数组,所以超出的部分丢弃掉

还是画图更能清楚的表达意思:

解题如下:

class Solution {
    public void duplicateZeros(int[] arr) {
        if (arr == null || arr.length == 0) return;
        //计算数组中0的个数
        int zeros = 0;
        for (int num : arr) {
            if (num == 0) {
                zeros++;
            }
        }
        if (zeros == 0) return;

        int len = arr.length;

        //计算数组的capacity和要走的步长
        int i = len - 1, j = i + zeros;

        while (i != j) {
            insert(arr, i, j--);
            if (arr[i] == 0) {
                //遇到0多走一步
                insert(arr, i, j--);
            }
            i--;
        }
    }

    private void insert(int[] arr, int i, int j) {
        //被丢弃的部分不参与运算
        if (j < arr.length) {
            arr[j] = arr[i];
        }
    }
}

step3: 证实猜想

果然印证了我们的想法,成功啦~~