储备知识
数组,赋值操作,指针
题目
给你一个数组 nums和一个值 val,你需要 原地 移除所有数值等于 val的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。
假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作:
- 更改
nums数组,使nums的前k个元素包含不等于val的元素。nums的其余元素和nums的大小并不重要。 - 返回
k。
思路
本题我们使用同向双指针方法可以高效解决
首先我们要知道,删除的本质还是覆盖,把数组中一个数值3赋值成4,那么3就被删除了。
所以我们只需要把目标值val的下一个数值赋值给val的位置,就达到了删除val保留其他数的目的
思路如下
一开始,两个指针都站在数组的第一个位置(下标 0)。
侦察兵(快指针fast)先走,每到一个新格子,他就判断:
如果这个格子里的东西正好是我们要删掉的 val,那侦察兵就自己记住,不告诉整理员(慢指针slow),直接跳过,继续往前走。
如果格子里的东西是我们需要保留的(不等于 val),侦察兵就把这个需要保留的数直接赋值到slow的那个位置。
整理员(慢指针)听到后,就把这个好东西拿过来,放到自己当前指向的位置,然后自己往前进一步(slow++),准备接收下一个需要的数。
侦察兵一直走到数组的尽头,整理员也就把所有的需要的数都按顺序堆在了数组的前面。
最后,整理员站的位置(slow)就是删除val后数组的长度。
代码实现
cpp
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
if (nums.empty()) {
return 0; //先判空,判断数组是否为空
}
//定义快慢指针,这里的fast定义与后面for循环里重复,建议删除,这里这样写是为了看起来结构易懂
int slow = 0;
int fast =0;
//开始遍历数组
for (int fast=0; fast < nums.size(); fast++) {
//注意if条件
if (nums[fast] != val) {
nums[slow] = nums[fast];
slow++;
}
}
return slow;//题目要求的是返回数组长度,此时slow的位置就是长度
} //注意不是返回nums[slow]那将返回最末尾的那个数值
};