算法笔记 -- 283. 移动零

93 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情

一、题目描述:

283. 移动零 - 力扣(LeetCode) (leetcode-cn.com)

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

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

 

示例 1:

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

示例 2:

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

提示:

  • 1 <= nums.length <= 10^4
  • -2^31 <= nums[i] <= 2^31 - 1  

进阶:你能尽量减少完成的操作次数吗?

二、思路分析:

如果暂时想不到很好的办法,可以采取直接暴力求解的方式,先获取所有的非零元素,再依次存入相应位置,其余位置则为0。该方法因为开辟了新的数组空间,并不符合题目要求,但是,对于该方法,是为了增加实现方案的可能性,从不同角度思考问题。假如题目没有空间限制,是不是该方法就可以适用于题目了呢。

  • 第一步:生成一个与nums数组相同长度的新数组;
  • 第二步:遍历nums数组,将非零元素依次存储入新数组中;
  • 第三步:循环遍历,依次将新数组中对应位置上的元素赋值于nums数组中

当然还有更好的办法那就是双指针法

通过设置双指针,快速进行移动零操作。

  • 第一步:设置指针head和tail,head默认为0,表示非零数的依次存储位置,tail则依次遍历的数组索引位置;
  • 第二步:如果tail指针位置元素是非零元素,则与head指针位置元素交换;

三、AC 代码:

class Solution {
    public void moveZeroes(int[] nums) {
        int[] tempNums = new int[nums.length];
        int index = 0;
        for(int i=0;i<nums.length;i++){
            if(nums[i] != 0)
                tempNums[index++] = nums[i];
        }
        for(int j=0;j<nums.length;j++){
            nums[j] = tempNums[j];
        }
    }
}
class Solution {
    public void moveZeroes(int[] nums) {
        int head = 0;
        for(int tail = 0; tail < nums.length; ++tail){
            if(nums[tail] != 0){
                int num = nums[head];
                nums[head] = nums[tail];
                nums[tail] = num;
                head++;
            }
        }
    }
}