算法练习第4道-移动零

284 阅读1分钟

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

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

思考

首先区分下数组有几种情况

  • 第一种数组没有0,直接返回
  • 第二种有00的情况下,我们如何操作?

方法1

最简单的方式,定义新数组,将不是0的数组填充进去,与此同时,我们也记录0出现的个数,形成一个0的数组,然后两个拼接在一起

实现如下:

判断当前数组是否存在有0

if(nums.indexOf(0) < 0) {
    return nums
}

然后创建newArrzeroArr,通过循环,产生一个非0数组和一个0数组

let newArr = [], zeroArr = []
  for(let i = 0; i < len; i++) {
    if(nums[i]>0) {
      newArr.push(nums[i])
    } else {
      zeroArr.push(0)
    }
  }

最后我们把数组拼接在一起

newArr.concat(zeroArr)

最后return出数组

完整代码如下

let moveZeroes = function(nums) {
  let len = nums.length
  if(nums.indexOf(0) < 0) {
    return nums
  }
  let newArr = [], zeroArr = []
  for(let i = 0; i < len; i++) {
    if(nums[i]>0) {
      newArr.push(nums[i])
    } else {
      zeroArr.push(0)
    }
  }
  return newArr.concat(zeroArr)
}

优化

上边的思考有一个问题,它并不是原地对数组进行操作的。那我们修改个对原地数组修改的方法

首先依然是空值判断,然后进行循环,这里的循环记录一个值,就是不为0的个数,让他们重新排序 但我们拿到这个值后,减取长度,我们就知道尾部有多个为0的参数

let index = 0
  for(let i = 0; i < len; i++) {
    if (nums[i] !== 0) {
      nums[index] = nums[i]
      index++
    }
  }

现在我们就把参数都按顺序移动到了前面,现在我们来替换后边的0

for(let i = index ; i < len; i++) {
    nums[i] = 0
 }

这个方法就满足了原地对数组修改

优化2

该方法使用sort,它有两个比较参数,属于可选参数

  • compareFunction(a, b)如果小于0, a会排在b之前
  • compareFunction(a, b)如果等于0, ab位置不变
  • compareFunction(a, b)如果大于0, a会排在b之后

具体方法为

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

说实在的,这个问题我暂时还不懂,需要去寻找下答案。

未完待续....