力扣100题-双指针移动0

90 阅读1分钟

题目:移动零

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

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

示例 1:

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

示例 2:

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

遇到一个问题

本来想用一下hash进行解决,打印输出的样例没有问题~ 但是提交就报错,后面发现是在不修改原数组的情况下进行移动!

 public static void moveZeroes(int[] nums) {
        // 定义一个LinkedList : 底层双链表实现
        LinkedList<Integer> list = new LinkedList<>();
        int temp = 0; // 用来统计0的数量
        for (int num : nums) {
            if (num == 0) {
                temp++;
                continue;
            }
            list.add(num);
        }
        list.sort(null); // 排序
        // 在末尾添加0 
        while (temp > 0) {
            list.add(0);
            temp--;
        }
        for (int i : list) {
            System.out.println(i);
        }
    }

官方双指针题解:

  • 如果没有遇到0,left和right就不交换位置,如果遇到0,left停止一次+1,right正常+1,下一步,进行替换操作
  • 注意替换,是把0替换到后面去
 public static void moveZeroes(int[] nums) {
        // 官方双指针解法
        // 误区:开始自己认为这个要进行排序,样例测试中并不需要排序,在不改变数组的情况下,对数组进行一个移动0操作
        int n = nums.length;
        int left =0,right =0;
     
        for (int i = 0; i < n; i++) {
            if(nums[right]!=0) {
                swap(nums,left,right);
                left++;
            }
            right++;
        }
    }
    private static void swap(int[] nums, int left, int right) {
        int temp = nums[left];
        nums[left]= nums[right];
        nums[right]=temp;
    }

优化一下

// 使用了一个替换的思想,先把所有非0的数,从nums[0]开始替换原来nums[0]的位置,替换完之后,把剩下的长度继续 // 循环,赋值为


    public static void moveZeroes(int[] nums) {
        int n = nums.length;
        int i = 0;

        for (int k = 0; k < n; k++) {
            if (nums[k] != 0)
                nums[i++] = nums[k];
        }
        for (int k = i; k < n; k++) {
            nums[k] = 0;
        }
    }