27. 移除元素
描述:
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用
O(1)额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例:
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
这里观察题目函数的返回值可以看到, 返回值是int, 也就是只需要删除指定元素后的数组长度, 第二个数组的输出不是本函数里的, 但是需要保证数组nums的前n位是删除后的数据, 后面的数据是什么不用关心.
思路:
- 第一想法就是新建一个数组来做, 但是题目约束了不可以使用其他的数组空间, 所以这个方法不行, 也的确没意义.
- 这里常用的方法就是双指针法, 这里的指针就是数组的索引值, 使用两个指针来指向数组中的元素, 快指针进行遍历数组, 慢指针进行数组元素的改变操作.
- 双指针法的具体流程如下(由于无法制作动图故采用文字描述):
- 开始的时候, 两个指针指向首元素
- 当前元素不是需要删除的元素val, 将快指针指向的元素值赋值给慢指针指向的元素, 之后慢指针slow++, 然后开始下个元素判断即快指针fast++
- 若当前元素是要删除的元素, 慢指针不做改动, 直接进入下个元素的判断fast++
- 当遍历结束, 直接返回慢指针, 由于有++操作, 所以慢指针(索引值)就是删除指定元素后的长度
代码:(C++)
/*
* @lc app=leetcode.cn id=27 lang=cpp
*
* [27] 移除元素
*/
// @lc code=start
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slow{0};
for(int fast = 0; fast < nums.size(); fast++){
if (nums[fast] != val){
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
};
- 时间复杂度:O(n),其中 n 为序列的长度。我们只需要遍历该序列至多两次。
- 空间复杂度:O(1), 我们只需要常数的空间保存若干变量。