27.移除元素

题目

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1: 给定 nums = [3,2,2,3], val = 3, 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 你不需要考虑数组中超出新长度后面的元素。
示例 2: 给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
你不需要考虑数组中超出新长度后面的元素。

思路

数组元素不能仅仅原地删除,删除掉某一值后,需要将此值后面的值拉上来填补空缺。

图解

由题目可知,其实是把=value的值全部移到数组的最后面,而不是value的部分移到数组的前面。
想到用两个指针,一个找到=value的值,一个找到!=value的值,把=value和!=value的值交换,这样就能把=value的值往后拉,!=value的值往前拉。
利用left、right指针。

  • left指针向前走,走到=value的地方停下,等待被换到后面去。
  • right指针往回走,走到!=value的地方停下,等待着被换到前面去。
    在这里插入图片描述

如上图,两个指针规定的位置停下。
left指向一个=value的值,right指向一个!=value的值。
这样,只需要把left和right指向的值进行交换,就是把value换到后面,而把不是value的值换到前面去了。
在这里插入图片描述

细节

循环条件

 while(right >= left)

这里为什么有=号?
按理来说,right停在不是value的地方left停在是value的地方,这两者是永远不会相等的。
这里其实是把一个边界条件考虑进去了:数组只有一个元素。nums.length=1,left=right。
指针移动和left、right交换谁先执行?

while(right >=left) {
       
        var temp = nums[left];
        nums[left] = nums[right];
        nums[right] = temp;

        if(nums[right] == val) {
            right--;
        }
        if(nums[left] != val) {
            left++;
        }
    }

一般指针的移动都是放在下面的。
因为如果把指针移动放在后面,指针移动后,就能去判断循环条件 right >= left,如果条件不满足就退出,这样不会出现交换时有指针是负数的情况。
最后返回数组长度
最后跳出循环时,left这一索引值,在最后一个!=value的值后面以个。#刚好是移除后数组的长度。
在这里插入图片描述

return right + 1;

完整代码

var removeElement = function(nums, val) {

    var left = 0;
    var right = nums.length - 1;


    while(right >=left) {
       
        var temp = nums[left];
        nums[left] = nums[right];
        nums[right] = temp;

        if(nums[right] == val) {
            right--;
        }
        if(nums[left] != val) {
            left++;
        }
    }

    return right + 1;
};
var removeElement = function(nums, val) {
// 构思:left、right两个指针
// 题目实际上是要求把value放在右边,不是value的放在左边
// 所以,left遇见了value,停下处理;而right得走到不是value的地方,等待别人来换它
// left、right相遇处就是终止条件 right < left

// 1.边界条件还没想清楚
// 这里所说的边界条件,其实是指nums只有1个或0个元素的情况。
    var left = 0;
    var right = nums.length - 1;

// 2.这里为什么是> 而不是 >=
    while(right > left) {
        // 3.交换和指针变换的顺序
        if(nums[right] == val) {
            right--;
        }
        if(nums[left] != val) {
            left++;
        }
        var temp = nums[left];
        nums[left] = nums[right];
        nums[right] = temp;
    }

    return right + 1;
    

};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值