力扣热题100题- 移动零


给定一个数组 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)
链接:https://leetcode.cn/problems/move-zeroes

想法1:双指针(我自己的想法,但是没有写出来,只能抄袭官方的)

我觉得自己没有想清楚的点在于

1.双指针到底指向的是什么?

class Solution {
    //双指针思路
    //双指针思路的重点是找到指针到底指的是什么?以及怎么将指针挪动。

    //指针x 是已处理好的尾部,y是待处理的数字的头部
    //这里简单解释下什么叫做处理?
    //处理的逻辑是指:将非0数字往前移动
    public void moveZeroes(int[] nums) {
        int n = nums.length ,x = 0 ,y = 0;

        //循环结束条件:没有待处理数字即可
        while(y < n){
            //如果发现待处理的数字为不等于0
            if(nums[y] != 0){
                //交换已处理好的尾部的和待处理数字的头部的值。
                swap(nums,x,y);
                //交换完之后,就把已处理的尾部数字+1
                x++;
            }
            //待处理数字头部+1
            y++;
        }
    }

    private void swap(int[] nums,int start,int end){
        int temp = nums[start];
        nums[start] = nums[end] ;
        nums[end] = temp;
    }
}

想法2:循环一次

class Solution {
    //思路,设置坐标,x标记非0的结束位置
    public void moveZeroes(int[] nums) {
        int x = 0;
        for(int i = 0; i < nums.length ; i++){
            if(nums[i] != 0){
                swap(nums,i,x);
                x++;
            }
        }
    }

    private void swap(int[] nums,int start,int end){
        int temp = nums[start];
        nums[start] = nums[end] ;
        nums[end] = temp;
    }
}

其实不难发现,两者基本一致。


文章作者: 冯廷鑫
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 冯廷鑫 !
  目录