(LeetCode-283)移动零

文章介绍了两种方法解决LeetCode题目283,即使用双指针策略将数组中的所有0移动到末尾,同时保持非零元素的相对顺序。第一种方法是分两步,第一次遍历记录非零个数,第二次遍历置0;第二种方法是一次遍历,类似快速排序思想,直接交换0和非0元素。
摘要由CSDN通过智能技术生成

题目

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

示例:

输入: [0,1,0,3,12]

输出: [1,3,12,0,0]

说明:

必须在原数组上操作,不能拷贝额外的数组。

尽量减少操作次数。

分析和解答

方法

依然可以用双指针的办法,两个指针i和j。i负责遍历整个数组,在遍历数组的时候,j用来记录当前所有非0元素的个数。遍历的时候每遇到一个非0元素就将其往数组左边挪,挪动到J所在的位置,注意是挪动,不是交换位置,j同时也移动一个位置。当第一次遍历完后,j指针的下标就指向了已经排完了位置的最后一个非0元素下标。

进行第二次遍历的时候,起始位置就从j开始到结束,将剩下的这段区域内的元素全部置为0即可。

     

      

   

  

时间复杂度是O(n),空间复杂度则变为O(1)。

方法2

还有一种一次遍历的方式,参考了快速排序的思想

代码
package com.jiawei.array;

import java.util.Arrays;

/**
 * ClassName: MoveZeroes_283
 * Package: com.jiawei.array
 * Description: (LeetCode-283)移动零
 *  给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
 *
 * @Author JiaWei-L
 * @Create 2024/1/14 23:51
 * @Version 1.0
 */
public class MoveZeroes_283 {

    /*双指针方式实现*/
    public void moveZeroes(int[] nums) {
        if(nums==null) {
            return;
        }
        //第一次遍历的时候,j指针记录非0的个数,只要是非0的统统都赋给nums[j]
        int j = 0;
        for(int i=0;i<nums.length;++i) {
            if(nums[i]!=0) {
                nums[j++] = nums[i];
            }
        }
        //非0元素统计完了,剩下的都是0了
        //所以第二次遍历把末尾的元素都赋为0即可
        for(int i=j;i<nums.length;++i) {
            nums[i] = 0;
        }
    }

    /*一次遍历,快速排序的思想*/
    public static void moveZeroes2(int[] nums) {
        if(nums==null) {
            return;
        }
        //两个指针i和j
        int j = 0;
        for(int i=0;i<nums.length;i++) {
            //当前元素!=0,就把其交换到左边,等于0的交换到右边
            if(nums[i]!=0) {
                int tmp = nums[i];
                nums[i] = nums[j];
                nums[j++] = tmp;
            }
        }
    }

    /*双指针方式实现,但是取消了第二次循环*/
    public static int[] moveZeroes4(int[] nums){
        if(nums==null) {
            return nums;
        }
        int j =0;
        for (int i = 0; i < nums. length; ++i) {
            if (nums[i] !=0){
                nums[j] = nums[i];
                if (i !=j) {
                    nums[i] = 0;
                }
                j++;
            }
        }
        return nums;
    }

    public static void main(String[] args) {
        int[] test = {0,1,0,3,12};

        MoveZeroes_283 moveZeroes283 = new MoveZeroes_283();

        moveZeroes283.moveZeroes(test);

        //System.out.println(moveZeroes283.moveZeroes(test));

        //moveZeroes(test);
        moveZeroes2(test);
        System.out.println(Arrays.toString(moveZeroes4(test)));
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值