1. 移除元素问题解析
今天我们来深入探讨LeetCode第27题"移除元素"的解法。这道题看似简单,但其中蕴含着数组操作的核心思想,也是面试中经常考察的基础算法题之一。
题目要求我们原地移除数组中所有等于给定值的元素,并返回新数组的长度。这里的"原地"意味着我们不能使用额外的数组空间,只能修改原数组。这个限制条件直接决定了我们的解题思路。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 问题理解与约束分析
2.1 题目要求拆解
首先,我们需要明确题目的几个关键要求:
- 原地修改:不能创建新数组,必须直接在原数组上操作
- O(1)空间复杂度:只能使用常数级别的额外空间
- 元素顺序可以改变:不需要保持原有顺序
- 不需要考虑超出新长度后的元素:只需确保前n个元素正确即可
2.2 常见误区
很多初学者(包括曾经的我)容易犯以下错误:
- 试图直接"删除"元素(实际上数组长度在JS中是不可变的)
- 使用filter等高级方法创建新数组(违反原地修改要求)
- 过度关注删除后的元素位置(其实题目允许顺序改变)
3. 双指针解法详解
3.1 基本思路
最优雅的解法是使用双指针技巧:
- 慢指针(k):记录下一个有效元素应该放置的位置
- 快指针(i):遍历整个数组
当快指针指向的元素不等于目标值时,我们将其复制到慢指针位置,然后两个指针都前进;当等于目标值时,只移动快指针。
3.2 代码实现
javascript复制var removeElement = function(nums, val) {
let k = 0; // 慢指针
for (let i = 0; i < nums.length; i++) {
if (nums[i] !== val) {
nums[k] = nums[i];
k++;
}
}
return k;
};
3.3 复杂度分析
- 时间复杂度:O(n),只需遍历数组一次
- 空间复杂度:O(1),只使用了常数空间
4. 优化解法:交换移除
4.1 当元素很少时
当要移除的元素很少时,前一种方法会做很多不必要的复制操作。我们可以优化为:当遇到要移
