【Leetcode】283. 移动零

151 阅读2分钟

题目描述

在这里插入图片描述

// 283. 移动零

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

// 示例:

// 输入: [0,1,0,3,12]
// 输出: [1,3,12,0,0]
// 说明:

// 必须在原数组上操作,不能拷贝额外的数组。
// 尽量减少操作次数。


题解

// 插入排序法
// 插入排序就是记录最小值min,然后将最小值min的左边元素整体右移一格,
// 再把min插入到前面,形成升序。
// 我们这里根据题意直接反过来,思路是一样的:
// 从右到左遍历nums元素,如果找到0元素,记录为zero,后将0元素右边的元素
// 整体左移(需要左移的元素是zero右边,且不超过nums边界的,且不为0的数)
// 左移完之后,再把zero插入到右边。如此循环即可。
//
// 执行用时:6 ms, 在所有 Java 提交中击败了10.60%的用户
// 内存消耗:38.7 MB, 在所有 Java 提交中击败了62.31%的用户
class Solution {
    public void moveZeroes(int[] nums) {
        for (int i = nums.length - 1; i >= 0; i--) {
            if (nums[i] == 0) {
                int j = i, zero = nums[i];
                while (j + 1 < nums.length && nums[j + 1] != 0) {
                    nums[j] = nums[j + 1];
                    j++;
                }
                if (j != i) {
                    nums[j] = zero;
                }
            }
        }
    }
}


// 不理解可以用下面代码看看中间过程
class Solution {
    public void moveZeroes(int[] nums) {
        for (int i = nums.length - 1; i >= 0; i--) {
            if (nums[i] == 0) {
                int j = i, zero = nums[i];
                while (j + 1 < nums.length && nums[j + 1] != 0) {
                    nums[j] = nums[j + 1];
                    j++;
                }
                if (j != i) {
                    nums[j] = zero;
                }
                arrPrint(nums);  // 打印int[]
            }
        }
    }

    public void arrPrint(int[] arr) {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int num : arr) {
            sb.append(num + ", ");
        }
        sb.delete(sb.length() - 2, sb.length());
        sb.append("]");
        System.out.println(sb.toString());
    }
}

// 双指针法
// 设定一个索引i,初始化为0。for循环遍历nums中所有的元素num,
// 将所有不为0的num值全部覆盖到i处,之后i右移,所以i(前期)就专门用于
// 不为0的num元素左移的遍历,for循环结束之后,nums中所有不为0的值将连续
// 排列到nums的前半部。遍历完nums中不为0的num之后,剩下的就是为0的元素了,
// i索引继续右移,把nums中后面没遍历的部分全部置0即可。
// 
// 按照实例[0,1,0,3,12]的过程如下:
// num
//  i   
// [0,1,0,3,12]
//   num
//  i    
// [0,1,0,3,12]
//   num
//    i    
// [1,1,0,3,12]
//     num
//    i    
// [1,1,0,3,12]
//       num
//    i    
// [1,1,0,3,12]
//       num
//      i    
// [1,3,0,3,12]
//          num
//      i    
// [1,3,0,3,12]
//          num
//         i    
// [1,3,12,3,12]
//
//         i    
// [1,3,12,3,12]
//         i    
// [1,3,12,0,12]
//           i    
// [1,3,12,0,0]
// 
// 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
// 内存消耗:38.6 MB, 在所有 Java 提交中击败了77.25%的用户
class Solution {
    public void moveZeroes(int[] nums) {
		int i = 0;
		for (int num: nums) {
			if (num != 0) {
				nums[i++] = num;
			}
		}
		while (i < nums.length) {
			nums[i++] = 0;
		}
    }
}