>[success] # 27. 移除元素
* 描述
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
* 示例 1:
~~~
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
~~~
* 示例 2:
~~~
输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。
~~~
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/remove-element
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/remove-element
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
>[danger] ##### js 第一次解法
* 如果当前位置值等于目标对象则删除(删除后不能移动指针此时值会前移动一位,因此此时指针为了对应后一个值不动,这样前移的值会对应指针),否则移动指针
![](https://img.kancloud.cn/d3/33/d333c7882cd8b2084d2b1a9c42d26165_622x827.png)
~~~
/**
* @param {number[]} nums
* @param {number} val
* @return {number}
*/
var removeElement = function(nums, val) {
const {length} = nums
let index = 0
while(length>index){
if(nums[index] === val){
nums.splice(index,1)
}else{
index++
}
}
return nums.length
};
~~~
* 类似思路
~~~
/**
* @param {number[]}
* @param {number}
* @return {number}
*/
var removeElement = function(nums, val) {
for(let i=0;i<nums.length;i++){
if(nums[i]==val){
nums.splice(i,1)
i--
}
}
};
~~~
>[info] ## 快慢指针
* 利用快慢指针将数组分为三个区域,**慢指针**,**快指针**,**已处理区域**,要移除指定val 其实可以理解为**保留非指定val 值**,因此只要将快指针指到的**非指定值**移动到**保留区**,最后慢指针之前值都为符合题意值。
* 图解要移除3
![](https://img.kancloud.cn/67/cf/67cfebcd253caa5dbfc40be1d279350c_2273x1846.png)
>[danger] ##### js
~~~
/**
* @param {number[]} nums
* @param {number} val
* @return {number}
*/
var removeElement = function(nums, val) {
let fast = 0
let slow = 0
while(fast<nums.length){
// 快指针指到值不等于当前值说明是要保留的
if(nums[fast] !== val){
// 将保留的值移动到慢指针
// 形成保留区域
nums[slow] = nums[fast]
slow++
}
fast++
}
return slow
};
~~~
>[danger] ##### java
~~~
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0;
int fast = 0;
while(fast < nums.length){
if(nums[fast] != val){
nums[slow] = nums[fast];
slow++;
}
fast++;
}
return slow;
}
}
~~~
>[info] ## 对撞指针
* 指针从左右两端开始出发,当左指针遇到要移除值时候,右指针移动缩小范围,可以理解一共有4个值其中存在两个要移除值,此时遇到第一个时候4-1=3,做减法移除
![](https://img.kancloud.cn/b3/c4/b3c464acbee4ea00a6de794976b5d5b8_2322x1449.png)
>[danger] ##### js
~~~
/**
* @param {number[]} nums
* @param {number} val
* @return {number}
*/
var removeElement = function(nums, val) {
let left = 0
let right = nums.length - 1
while(left < right){
// 如果left 值等于移除值 移动right
if(nums[left] === val){
// 一直要让left 和right 交换后left 现在值不为移除值
nums[left] = nums[right]
right --
}else{
// 如果left 不为移除值才能移动
left ++
}
}
return right + 1
};
~~~
>[danger] ##### java
~~~
class Solution {
public int removeElement(int[] nums, int val) {
int rihgt = nums.length - 1;
int left = 0;
while( left <= rihgt ){
if( nums[left] == val ){
nums[left] = nums[rihgt];
rihgt--;
}else{
left++;
}
}
return rihgt + 1;
}
}
~~~
- 刷题准备
- 统计数组中元素出现次数
- Leetcode -- 442数组中重复的数据
- leetcode -- 448 找到所有数组中消失的数字
- 字符类似题
- Leetcode -- 1002 查找共用字符
- Leetcode -- 1370上升下降字符串
- 指针类题解
- Leetcode -- 283 移动零
- Leetcode -- 26. 删除有序数组中的重复项
- Leetcode -- 80. 删除有序数组中的重复项 II
- Leetcode -- 27. 移除元素
- Leetcode -- 344. 反转字符串
- Leetcode -- 125 验证回文串
- Leetcode -- 11 盛最多水的容器
- Leetcode -- 1480. 一维数组的动态和