LeetCode 27. 移除元素:从思路到代码,一篇吃透
不管是日常刷题还是面试手撕代码LeetCode 27 移除元素都是数组模块的入门必做题。题目难度不高但藏着数组操作的核心思想吃透这道题能帮你打下扎实的数组基础应对同类变形题也更得心应手。一、题目回顾给你一个数组nums和一个值val你需要原地移除所有数值等于val的元素。元素的顺序可能发生改变然后返回数组中与val不同的元素的数量。要求原地修改数组不能开辟新的数组空间只需要保证数组前 k 个元素是有效元素剩余元素不用处理返回值为有效元素的个数 k示例输入nums [3,2,2,3]val 3输出2结果数组前两位变为 [2,2]后面的元素可以忽略二、解题思路快慢双指针法这道题的最优解法是双指针法也叫快慢指针法思路简单易懂效率拉满。核心逻辑用一个慢指针 k专门记录有效元素的存放位置初始值为0遍历整个数组遇到不等于 val 的元素就把它放到nums[k]的位置然后 k 向后移动一位遍历完成后k 就是有效元素的总数数组前 k 位就是去重后的结果这种方法不用开辟新数组全程在原数组上操作满足题目原地修改的要求时间复杂度O(n)空间复杂度O(1)是这道题的标准解法。三、极简代码实现C 范围for版本相比传统的for循环C11的范围for循环写法更简洁可读性更高遍历容器不用手动管理索引非常适合这道题。class Solution { public: int removeElement(vectorint nums, int val) { // 慢指针记录有效元素存放位置 int k 0; // 范围for遍历数组所有元素 for (int num : nums) { // 保留不等于val的元素 if (num ! val) { nums[k] num; } } // 返回有效元素个数 return k; } };四、代码逐行解析参数说明vectorint nums是引用传递保证函数内修改直接作用于原数组不会产生副本慢指针k初始为0每存入一个有效元素k就自增指向下一个待写入的位置范围for循环自动遍历数组每一个元素num代表当前遍历到的元素写法简洁不易出错筛选有效元素判断当前元素是否等于val不等于就存入数组等于则跳过返回值返回有效元素个数k调用方根据k截取前k个元素即可五、高频疑问为什么返回k就行很多新手都会疑惑函数只返回了一个数字k为什么系统能拿到正确的数组结果这里有两个关键点一定要弄懂原地修改数组是引用传递代码已经把有效元素依次覆盖到了数组的前半部分原数组已经被修改约定规则返回的k是有效元素的数量系统默认数组前k个元素是结果k之后的元素可以忽略不用处理举个例子nums [3,2,2,3]执行完代码后数组变成 [2,2,3,3]返回k2系统只取前两位 [2,2] 作为答案判定正确。六、易错点提醒1. 禁止开辟新数组题目明确要求原地修改不能新建一个数组存放结果否则不符合题意面试会直接失分。2. 不要移动多余元素不用在意k之后的元素是什么也不用特意删除或者清空题目不做要求浪费操作反而降低效率。3. 指针使用规范避免出现指针越界、重复自增等问题比如不要在循环里写两次k会导致有效元素存放错位。七、拓展传统for循环版本如果不习惯用范围for用普通的索引for循环也能实现思路完全一致只是遍历方式不同。class Solution { public: int removeElement(vectorint nums, int val) { int k 0; for (int i 0; i nums.size(); i) { if (nums[i] ! val) { nums[k] nums[i]; } } return k; } };八、总结LeetCode 27 移除元素是数组双指针思想的入门题核心就是原地修改双指针筛选。范围for版本代码更简洁优雅适合日常刷题传统for循环更直观适合新手理解。两种写法底层效率一致掌握任意一种都能轻松拿下这道题。这道题的思想还能迁移到去重、元素替换等同类数组题吃透它数组基础题就稳了。