LC283. 移动零(第14题)

171 阅读3分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

菜鸟就要从第14题继续

一、题目描述:

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

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

  示例 1:

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

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

提示:

1 <= nums.length <= 104 -231 <= nums[i] <= 231 - 1

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/mo… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思路分析:

第一版:首先理解题意,强调了不复制数组的情况下原地对数组进行操作,因此直接遍历的方式就不写了,也比较简单。通过splice和push方法删除原位置的0,并在后面增补。注意一下这块的遍历i和数组的取值index不是一个,因为splice处理后会修改数组。

双指针:操作删除再新增虽然直观,但要操作数据长度变化。通过双指针可以不断的进行交换,最终达到效果。左指针指向当前已经处理好的序列的尾部,右指针指向待处理序列的头部。指针不断向右移动,每次右指针指向非零数,则将左右指针对应的数交换,同时左指针右移。

  • 左指针左边均为非零数;
  • 右指针左边直到左指针处均为零。

双指针第二版:在第一版的基础上,注意到右指针其实就是循环次数i,合并掉。另外本来想再加一层是否同位置可以不判断,想了想也没太大的必要。同时要注意左指针指向第一个数时,不一定是0,所以交换是必要的,而不能直接写后面的置为0。当然也可以筛选出特殊情况处理,但没必要。

一行代码版:还看到了有人写的一行代码版,很有趣利用sort排序。判断1,b是否为0,把为0的放在后面,都是0不用变。

  • 如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;

  • 如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。备注: ECMAScript 标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如 Mozilla 在 2003 年之前的版本);

  • 如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前。

要注意一点我看到有人的代码能通过测试执行,他只判断了b是否为0,这样在同样输入的情况下,其实对于[0,1]和[1,0]返回的顺序并不一致,但测试的时候都是返回了[1,0],有点搞不懂。

nums.sort((a,b) => b? 0: -1)

三、AC 代码:

1、第一版

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes = function(nums) {
    let index=0
    for(let i=0;i<nums.length;i++){
        if(nums[index]==0){
            nums.splice(index,1)
            nums.push(0)
        }
        else{
            index++
        }
    }
};

2、双指针(第一版)

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes = function(nums) {
    let n = nums.length
    let left = 0, right = 0
    for(let i = 0; i < n; i++){
        if(nums[i]!=0){
            temp = nums[left]
            nums[left] = nums[right]
            nums[right] = temp
            left ++
        }
        right++
    }
}

3、双指针(第二版)

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes = function(nums) {
    let n = nums.length
    let left = 0
    for(let i = 0; i < n; i++){
        if(nums[i]!=0){
            temp = nums[left]
            nums[left] = nums[i]
            nums[i] = temp
            left ++
        }
    }
}

4、一行代码版

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
 var moveZeroes = function(nums) {
     nums.sort((a, b) => a === 0 ? b !== 0 ? 1 : 0 : b === 0 ? -1 : 0)
};