LeetCode/27.移除数组

27.移除数组

题目

27. 移除元素

不用辅助数组,原地移除(删除)数组nums中的等于val的元素,被移出的部分不用管

三种方法
(重点)快慢双指针:把一个数组当两个用(顺序不变)
  • 快指针:遍历旧数组,找要装进新数组的元素
  • 慢指针:新数组下标
/**
 * @param {number[]} nums
 * @param {number} val
 * @return {number}
 */
var removeElement = function(nums, val) { //快(老)慢(新)双指针
    let slow = 0 //慢指针相当于新的数组下标
    for (let fast = 0; fast < nums.length; fast++) { //快指针遍历旧数组
        if (nums[fast] !==  val) { //不是要移除元素时加入新数组
            nums[slow++] = nums[fast]
        }
    }
    return slow //返回数组个数
};
前后双指针:把不要的数移到最后(顺序变)
    • 前指针:从前面开始找找不要的数
    • 后指针:从后面找要的数,交换

img

/**
 * @param {number[]} nums
 * @param {number} val
 * @return {number}
 */
var removeElement = function(nums, val) { //前(找要删)后(找不删)双指针
  let l = 0,r = nums.length - 1; //区间为左闭右闭[]
  
  while(l <= r){  //继续循环,进行下一次查找的条件
    // 下面加 l <= r 是为了防止找的时候 指针穿过 
    while(l <= r && nums[l] !== val) l++; //找左边=val要删的值 
    while(l <= r && nums[r] === val) r--; //找右边!=val不删的值
    // 一定要l < r时才覆盖,最后一次退出循环时,l > r不能交换
    if(l < r) nums[l++] = nums[r--];//用不删的值覆盖要删的
    //保持指针指向下一个要判断的值
  }

  return l; //l找被移除的,最后正好是指向第一个不满足的,也就是size大小
};

最后代码还是很简洁滴~

let l = 0, r = nums.length - 1
while (l <= r) {
    while (l <= r && nums[l] !== val) l++
    while (l <= r && nums[r] === val) r--
    if(l < r) nums[l++] = nums[r--]
}
return l
注意暴力解法的代码细节(顺序不变)
  1. i先找到要删的数
  2. 把后面的都往前移一位
  • 注意:因为i后所有数都前移了一位,i也得往前移一个,才能下一次for循环i++后指向下一个要判断的值(不然直接++会跳过刚移到i位置上的数)
  • 在移动的过程中数组长度变化,循环条件应该为变化的size
/**
 * @param {number[]} nums
 * @param {number} val
 * @return {number}
 */
var removeElement = function(nums, val) { //暴力
  let size = nums.length //nums.length为数组实际大小不会改变,size等会要返回的删除之后的大小
  for (let i = 0; i < size; i++) {
    if (nums[i] === val) { //找到要删除的值
      for (let j = i + 1; j < size; j++) {
        nums[j-1] = nums[j]
      }
      size--; //数组大小减一
      i--; //i后面的值都向前移动了一位,如果i不前移,接下来执行i++会跳过一个数没判断,所以一定要i--
    }
  }
  return size
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值