leetcode笔记之[283. 移动零]

47 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情

一、题目描述:

283. 移动零 - 力扣(LeetCode)

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

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

示例 1:

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

示例 2:

输入: nums = [0]
输出: [0]

  提示:

  • 1 <= nums.length <= 10^4
  • -2^31 <= nums[i] <= 2^31 - 1  

进阶:你能尽量减少完成的操作次数吗?

二、思路分析:

问题的关键在于:移动之后数组中的数字位置保持不变

根据上面的原则,我们可以使用不改变数字原本的位置,但是可以改变0的位置

1、我们定义一个变量记录当前0的位置;
2、每次遇到0时,增加0的个数
3、每次遇到数字时,将数字与当前0交换位置
4、根据剩下0的个数判断,下一个0的位置是+1,还是交换之后的位置

三、AC 代码:

func moveZeroes(_ nums: inout [Int]) {

    var zeroIndex = -1
    var zeroCount = 0

    for i in 0..<nums.count {
        if nums[i] == 0 {
            // 遇到0时
            // 如果index为-1,则将index指向当前位置
            // 如果index不为-1,则0的个数+1
            if zeroIndex == -1 {
                zeroIndex = i
            }

            zeroCount += 1
        } else {
            // 如果当前数不为0的话
            // 判断之前是否有0
            // 之前没有0,则不做处理
            // 之前有0的位置,则交换位置
            if zeroIndex != -1 {
                let temp = nums[i]
                nums[i] = 0
                nums[zeroIndex] = temp
                
                // 交换结束之后,更新0的位置
                if zeroCount > 0 {
                    zeroIndex += 1
                } else {
                    zeroIndex = i
                }
            }
        }
    }

}

范文参考

遍历数组,第i个如果为0,那么遍历i+1过后所有元素,遇到的第一个不为零(记为j)的元素,那么就让第i个元素的值为j,第j个元素值为0,遍历完过后就完成了 - 移动零 - 力扣(LeetCode)

不开辟数组将数组里面的0全部移动到数组后面且相对不改变顺序 - 移动零 - 力扣(LeetCode)