JavaScript 经典算法面试题 - 移动零

题目

给定一个数组nums, 编写一个函数将所有 0 移动到它的末尾,同时保持非零元素的相对顺序。
例如, 定义 nums = [0, 1, 0, 3, 12],调用函数之后, nums 应为 [1, 3, 12, 0, 0]。

注意事项:

必须在原数组上操作,不要为一个新数组分配额外空间。
尽量减少操作总数。

解法一:

思路:查找出数组中所有的0,从数组中移除后立刻push到数组末尾。其中参数b用来记录移动数量,当索引为length-b时,后面的数已全部为0,可以中断遍历。i–的作用:从java的角度来说,数组元素是不能在for循环中删除的,因为这样会改变数组的长度,导致异常抛出,必须使用迭代器遍历数组才能安全删除元素,此处JavaScript的splice方法会直接改变数组长度,从而导致后面的元素索引变化,故需将索引向前移动一位,以确保无元素遗漏。
var moveZeroes = function(nums) {
   	let b = 0;
 	for (let i = 0; i < nums.length; i++) {
      if(i === nums.length-b){
          break;
      }
      if (nums[i] === 0) {
        nums.splice(i, 1);
        nums.push(0);
         b++;
         i--
      }
    }
};

解法二

思路:双指针法,解法一中有提到,在for循环中遍历时删除数组元素是一种不安全的操作(JavaScript中是否属于安全操作?待思考~),那么,可以将解法进行优化,使用双指针比较来代替数组遍历次数。实现思路和解法一相同,先移除元素后push末尾

var moveZeroes = function(nums) {
  const max = nums.length

  let start = 0
  let end = max - 1

  while (start < end) {
    const item = nums[start]
    if (item === 0) {
      nums.splice(start, 1)
      nums.push(0)
      end--
      continue
    }
    start++
  }
};

解法三

思路:将数组中所有的0元素全部移除,然后根据移除数量进行push操作,此法简单粗暴,元素较多时会比较消耗时间。
var moveZeroes = function(nums) {
    let count =0
 	for (let i = 0; i < nums.length; i++) {
      if (nums[i] === 0) {
        nums.splice(i, 1);
        i--;
        count++;
      }
    }
    
    for(let j = 0;j<count;j++){
        nums.push(0);
    }
};

此题难度较为简单,考虑细节点可能有:

  1. 数组删除时的索引变化
  2. 数组索引的移动量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值