LeetCode 283 – 移动零

题目描述

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

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]

示例 2:
输入: nums = [0]
输出: [0]

题目分析

双指针冒泡

将所有 0 移动到末尾,很容易联想到冒泡排序,但如果先把第一个 0 移动到最后,再来处理下一个 0 ,就需要 2 层循环,时间复杂度 O(n^2)
更好的思路是,使用双指针 left 和 right,left 指向当前第一个0,right 指向当前第一个在 0 后的非 0 数字,让这两个数字互换位置。
left 和 right 初始值都是 0,如果当前数字是 0 则 right 前进一位,如果是非0则 left 和 right 都前进一位。每次发生数字互换后,left 和 right 都前进一位。
时间复杂度 O(n)

原地重写(推荐)

遍历数组,记录非0数字的个数 p,如果当前是非0数字,直接把它放在预期的位置 p-1。全部遍历完之后,再把 >=p 的位置都修改成 0。
时间复杂度 O(n)

Java

public void moveZeroes1(int[] nums) {
    int left = 0;
    int right = 0;
    while (right < nums.length) {
        if (nums[right] != 0) {
            if (left != right) {
                int t = nums[left];
                nums[left] = nums[right];
                nums[right] = t;
            }
            left++;
        }
        right++;
    }
}

public void moveZeroes2(int[] nums) {
    int p = 0; // 非0数字总数
    for (int i = 0; i < nums.length; i++) {
        if (nums[i] != 0) {
            p++;
            nums[p - 1] = nums[i];
        }
    }
    for (int i = p; i < nums.length; i++) {
        nums[i] = 0;
    }
}

Kotlin

fun moveZeroes1(nums: IntArray) {
    var left = 0
    var right = 0
    while (right < nums.size) {
        if (nums[right] != 0) {
            if (left != right) {
                val t = nums[left]
                nums[left] = nums[right]
                nums[right] = t
            }
            left++
        }
        right++
    }
}

fun moveZeroes2(nums: IntArray) {
    var p = 0 // 非0数字总数
    for (i in nums.indices) {
        if (nums[i] != 0) {
            p++
            nums[p - 1] = nums[i]
        }
    }
    for (i in p until nums.size) {
        nums[i] = 0
    }
}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部