283. Move Zeroes

Question

Given an array nums, write a function to move all 0’s to the end of it while maintaining the relative order of the non-zero elements.For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0].

Note:

1.You must do this in-place without making a copy of the array.

2.Minimize the total number of operations.

思路一

对数组内的元素进行遍历,如果是非0则跳过,如果是0则在后面的元素中找到一个非零的元素,两个元素交换位置。

代码
public class Solution {
    public void moveZeroes(int[] nums) {
        for(int i = 0;i < nums.length;i++){
            if(nums[i] != 0)
                continue;
            else{
                for(int j = i + 1;j < nums.length;j++){
                    if(nums[j] == 0)
                        continue;
                    else{
                        nums[i] = nums[j];
                        nums[j] = 0;
                        break;
                    }
                }
            }

        }
    }
}
结果及分析

【%6】及其低效的一个算法。

思路二

之前看到过一个很巧妙的办法,不过后来忘了,因为题目中要求不能新建一个数组,只能在这一个数组上操作。其实可以对数组进行遍历,同时设置一个标志位,如果遍历到的元素为0,则标志位不变。如果遍历到的元素非0,则把元素赋值到标志位对应的数组中,同时标志位+1,我觉得还是代码能够说清楚。

代码
public class Solution {
    public void moveZeroes(int[] nums) {
        int index = 0;
        for(int i = 0;i < nums.length;i++){
            if(nums[i] != 0){
                nums[index] = nums[i];
                index++;
            }
        }
        for(;index < nums.length;index++){
            nums[index] = 0;
        }
    }
}
结果及分析

【You are here!
Your runtime beats 22.98% of javasubmissions.】O(n)的时间复杂度,感觉是最优的了。

二刷 思路三

最好不要在if中嵌套if,不专业。所以对思路进行改进,如果尾指针的元素不为0,则跳过,包括数组一开始就有一堆非0的数字,当第一次出现0的时候,头指针继续向前走,尾指针不动,当头指针遇到非0的元素,头尾指针交换数组的内容同时尾指针向前移动一次。

代码
public class Solution {
    public void moveZeroes(int[] nums) {
        if(nums == null || nums.length <= 0)
            return;
        for(int head = 0,tail = 0;head < nums.length;head++){
            if(nums[tail] != 0){
                tail++;
                continue;
            }
            if(nums[head] != 0){
                nums[tail] = nums[head];
                nums[head] = 0;
                tail++;
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值