力扣27题最优解:巧用左右指针,3分钟攻克原地操作
题目要求从整数数组中原地移除所有等于给定值 val 的元素,并返回新的数组长度。最终数组的前 n 个位置应为非 val 的元素,且元素的顺序可以改变。例如,输入 nums = [3,2,2,3], val = 3,移除后数组前 2 个元素为 [2,2],返回长度 2。需要注意两个要求:原地修改数组和使用空间复杂度为 O(1) 的算法。
解题思路与过程
1.双指针技巧
使用左右两个指针(l 从左向右,r 从右向左)快速定位需要移除的元素。
2.交换与覆盖策略
当左指针 l 遇到 val 时,将其与右指针 r 指向的元素交换,并将右指针左移,跳过已被处理的元素。这意味着所有等于 val 的元素逐渐被“推”到数组末尾。
3.动态调整有效长度
每次交换后,数组的有效长度 n 减 1,确保后续循环不会处理末尾已被标记的元素。
4.终止条件
循环持续直到左指针 l 超过右指针 r,此时所有非 val 元素已集中在数组前 n 个位置。
代码:
class Solution { public: int removeElement(vector<int>& nums, int val) { int n = nums.size(); // 初始化有效长度为数组总长 int l = 0, r = n - 1; // 左右指针分别指向数组首尾 while (l <= r) { // 当左指针未越过右指针时循环 if (nums[l] == val) { // 左指针遇到目标值 // 交换左指针和右指针的值,将目标值移到数组末尾 int tmp = nums[l]; nums[l] = nums[r]; nums[r] = tmp; r--; // 右指针左移,缩小处理范围 n--; // 有效长度减1,排除末尾的val } else { l++; // 左指针右移,保留当前非val元素 } } return n; // 返回最终有效长度 } };
原创内容 转载请注明出处