Skip to content

Latest commit

 

History

History
114 lines (89 loc) · 3.52 KB

20200530-283.move-zeroes.md

File metadata and controls

114 lines (89 loc) · 3.52 KB

283.move-zeroes

题目链接:https://leetcode-cn.com/problems/move-zeroes/

参考链接:

https://leetcode-cn.com/problems/move-zeroes/solution/yi-dong-ling-by-leetcode/

https://leetcode-cn.com/problems/move-zeroes/solution/dong-hua-yan-shi-283yi-dong-ling-by-wang_ni_ma/

题目

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

示例 1:

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

说明:

  1. 必须在原数组上操作,不能拷贝额外的数组。
  2. 尽量减少操作次数。

解题

思路[1]去零补零

  • 这个题可以拆解成两个步骤:
    • 数组前面为数组中的非零元素[按顺序],
    • 数组后面全是零
  • 所以就涉及到去零和补零的操作,这两个操作的顺序和方法不同就有了多个不同的解法

代码

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
// 双指针去零,慢指针指向存储位置,快指针遍历数组,遇到非零元素就将其放到慢指针的位置。遍历一遍后完成移动。最后通过,jsAPI的`fill`补零
var moveZeroes = function(nums) {
  var k = 0;
  for(var i = 0; i < nums.length; i++){
    if(nums[i] === 0){
      continue;
    }
    nums[k] = nums[i];
    k++;
  }
  nums.fill(0, k, nums.length)
};

// 通过filter找到非零元素(去零),fill构建全部为零的数组(补零),splice和扩展运算符进行数组重组,本质上还是去零和补零
var moveZeroes = function(nums) {
    var numsF = nums.filter(v => v !== 0);
    nums.splice(0, nums.length, ...numsF, ...Array(numsF.length).fill(0));
};

// 一次遍历,遇到零就通过splice删除(去零),然后在结尾push0(补零)
var moveZeroes = function(nums) {
  let n = nums.length;
  for(let i=n-1;i>=0;i--){
    if(nums[i]===0){
      nums.splice(i,1)
      nums.push(0)
    }
  }
};

思路[2]遍历交换元素

  • 双指针,也是快指针和慢指针交换元素,是思路一的第一种解法的进阶版,思路一只考虑到前N个为非零元素,想着覆盖就好,然后补零。
  • 如果扩宽一下思路,什么时候需要交换元素呢,就是前面有元素为0[一个或者多个],当前元素不为0的时候,将当前元素和第一个为0的元素交换。
  • 也就是说我们需要一个快指针遍历数组的同时,需要一个慢指针指向第一个为0的,也就是当有元素为0时,慢指针停止移动,快指针继续向前,找到不为0的值,使两者交换,并且向前移动慢指针。

代码

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes = function(nums) {
  let j = 0;
  for (let i = 0; i < nums.length; i++) {
    if (nums[i] !== 0) {
	  	// 普通交换元素,这里也是可以加一个判断:慢指针是否指向元素为0
      [nums[j], nums[i]] = [nums[i], nums[j]];
      // 因为只有在慢指针指向元素为0,而快指针指向元素不为0的时候才需要交换,而且交换的元素为0,所以可以进行一下操作
      // if (nums[j] === 0) {
      //  nums[j] = nums[i];
      //  nums[i] = 0;
      // } 
      j++
    }
  }
};

思考

  • 还是双指针的思路,最开始只想到了覆盖,没有想到可以替换
  • 双指针的思路在数组的算法题中经常使用,以后要多考虑一下,而且要思考一下有没有有没有更有解
  • 交换元素可以用js的解构