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

示例:

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/move-zeroes

简单版

将所有非0元素提取出来存入集合中,按顺序填充,未填充部分都填充0即可

  1. public void moveZeroes(int[] nums) {
  2. ArrayList<Integer> noneZeroList = new ArrayList<>();
  3. for (int i = 0; i < nums.length; i++) {
  4. if (nums[i] != 0) {
  5. noneZeroList.add(nums[i]);
  6. }
  7. }
  8. for (int i = 0; i < noneZeroList.size(); i++) {
  9. nums[i] = noneZeroList.get(i);
  10. }
  11. for (int i = noneZeroList.size(); i < nums.length; i++) {
  12. nums[i] = 0;
  13. }
  14. }

将三个for循环优化成两个for循环,但总体效率一样,使用一个List存非0数,一个list存0,然后将两个list聚合

  1. public void moveZeroes(int[] nums) {
  2. ArrayList<Integer> noneZeroList = new ArrayList<>();
  3. ArrayList<Integer> zeroList = new ArrayList<>();
  4. for (int i = 0; i < nums.length; i++) {
  5. if (nums[i] != 0) {
  6. noneZeroList.add(nums[i]);
  7. } else {
  8. zeroList.add(nums[i]);
  9. }
  10. }
  11. noneZeroList.addAll(zeroList);
  12. for (int i = 0; i < noneZeroList.size(); i++) {
  13. nums[i] = noneZeroList.get(i);
  14. }
  15. }

优化版

不需要新建一个List,定义一个整型变量index用于保存非0数的个数

  1. public void moveZeroes(int[] nums) {
  2. int index = 0;
  3. for (int i = 0; i < nums.length; i++) {
  4. if (nums[i] != 0) {
  5. nums[index] = nums[i];
  6. index++;
  7. }
  8. }
  9. for (int i = index; i < nums.length; i++) {
  10. nums[i] = 0;
  11. }
  12. }

交换法

将非0数和0交换位置,定义一个变量index用于记录0的下标,遍历到非0数就交换

  1. public void moveZeroes(int[] nums) {
  2. int index = 0;
  3. for (int i = 0; i < nums.length; i++) {
  4. if (nums[i] != 0) {
  5. swap(nums, i, index++);
  6. }
  7. }
  8. }
  9. public static void swap(int[] nums, int i, int j) {
  10. int temp = nums[i];
  11. nums[i] = nums[j];
  12. nums[j] = temp;
  13. }