LeetCode刷题(二)移动零

一.题目

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。

二.解题思路

本题的解题思路主要还是用的快速排序的思想,首先要确定一个待分割的元素做中间点X,然后把所有小于等于X的元素放在左边,大于X的元素放在右边。
这的中间点就是0本身,所以实现起来比快速排序简单很多,我们使用两个指针i和j,只要nums[i]!=0,我们就交换nums[i]和nums[j]

三.答案 一

public void moveZeroes(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 void moveZeroes(int[] nums)  {
    int length;
    if (nums == null || (length = nums.length) == 0) {
        return;
    }
    int j = 0;
    for (int i = 0; i < length; i++) {
        if (nums[i] != 0) {
            if (i > j) {// #1
                nums[j] = nums[i];
                nums[i] = 0;
            }
            j++;
        }
    }
}

四.难点详解

一.题目理解起来并不难,解法一注意的点就一个: j++是j先参与本行语句的其他运算,其他运算完成之后,j再自加1。。++j是j先自加1,再参与其他运算 这个概念别弄混了就行。

二.答案二主要是针对答案一的优化,其实优化的地方就是#1处。它避免了数组开头是非零元素的交换也就是阻止(i==j)时交换。
当i > j 时,只需要把 i 的值赋值给j 并把原位置的值置0。同时这里也把交换操作换成了赋值操作,减少了一条操作语句,理论上能更节省时间。

五.结语
路漫漫其修远兮,吾将上下而求索,哈撒给…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值