LeetCode——移动零(三种解法)

386 阅读3分钟

「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战」。

前言

大家好,我是程序猿小白 GW_gw,很高兴能和大家一起学习进步。

以下内容部分来自于网络,如有侵权,请联系我删除,本文仅用于学习交流,不用作任何商业用途。

摘要

本文主要介绍LeetCode题目移动零的一些解法和思路。

【题目】

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

  示例 1:

输入: nums = [0,1,0,3,12] 输出: [1,3,12,0,0] 示例 2:

输入: nums = [0] 输出: [0]  

提示:

1 <= nums.length <= 104

-231 <= nums[i] <= 231 - 1

题目链接:leetcode-cn.com/leetbook/re…

【解法一】

要求要把0元素放到数组末尾,一个很容易想到的方法就是遍历数组,如果遇到0元素就把它放到最后面。但是这样如果不影响位置就要每次都把最后一个元素之前的元素往前挪,很麻烦。我们可以转换一下思路,把非0元素往前挪不就好了。

【思路】

  1. 设置指针指向非0元素的下界位置,即index之前的元素都是非零元素。

  2. 遍历数组。

    1. 如果元素为0,则不进行操作。
    2. 如果元素不为0,则把num[i]的值赋给num[index],并且把index++。
  3. 最后把index之后的元素全部赋值为0。

【代码】

public void moveZeroes(int[] nums) {
       int index=0;
       for (int i = 0; i < nums.length; i++) {
           if(nums[i]!=0){
              nums[index++] = nums[i];
           }
       }
       while (index < nums.length) { 
           nums[index++] = 0; 
       }
}

【解法二】

【思路】

  1. 初始化两个指针,front为第一个0的位置,rear为第一个不为0的位置
  2. 接着front指针寻找为值为0的元素,rear指针寻找值不为0的元素,找到就停下来等待另一个指针,都找到了就开始交换 要时刻判断数组是否越界!!!

【代码】

public void moveZeroes(int[] nums) {
    int front = 0;
    //初始化两个指针的位置
    while (front < nums.length && nums[front] != 0) {
        front++;
    }
    int rear = front + 1;
    while (rear < nums.length && nums[rear] == 0) {
        rear++;
    }
    //始终判断数组是否越界
    while (rear < nums.length && front < nums.length) {
        while (front < nums.length && nums[front] != 0) {
            front++;
        }
        while (rear < nums.length && nums[rear] == 0) {
            rear++;
        }
        if (rear < nums.length && front < nums.length) {
            nums[front] = nums[rear];
            nums[rear] = 0;
        }
    }
}

【解法三】

【思路】

  1. 设置count用来统计i前面0的个数,
  2. 遍历数组
    1. 如果i对应的值为0,就让count++。
    2. 如果i对应的值不为0并且前面存在0,即count值不为0,就把当前的值放到第一个0的位置,即下标为i-count的位置,然后把当前位置赋值为0;

【代码】

public static void moveZeroes1(int[] nums) {
    /*
    解法3:统计0的个数
     */
    int count = 0;
    for (int i = 0; i < nums.length; i++) {
        if (nums[i] == 0) {
            count++;
        } else if(count!=0){
            nums[i-count] = nums[i];
            nums[i]=0;
        }
    }
}

小结

以上就是LeetCode移动零的三种解法,第一种最容易想到,最后一种比较巧妙,第二种用了排序算法的一些思想,虽然看起来麻烦,但是还是比较好理解,希望以上内容能对读者有所帮助,如有不正之处,欢迎留言指正。