
方法一:双指针
int removeElement(int* nums, int numsSize, int val) {
int low = 0; // 慢指针:标记新数组的有效存储位置
for (int fast = 0; fast < numsSize; fast++) { // 快指针:遍历整个数组
if (nums[fast] != val) { // 筛选出不等于val的有效元素
nums[low] = nums[fast]; // 将有效元素存入慢指针位置
low++; // 慢指针后移,准备存下一个有效元素
}
}
return low; // 慢指针最终位置 = 有效元素个数
}
核心逻辑
- 快指针 :遍历数组,负责 "找" 有效元素(≠
val)。 - 慢指针:负责 "存" 有效元素,标记新数组的边界。
- 最终
low即为新数组长度,数组前low个元素为有效结果
方法二:双指针优化
左右双指针法 的高效实现,核心是用右侧有效元素覆盖左侧待删除元素,减少不必要的赋值操作,完全满足题目 "原地移除" 的要求。
int removeElement(int* nums, int numsSize, int val) {
int left = 0, right = numsSize; // 右指针初始为数组长度(而非最后一个索引)
while (left < right) {
if (nums[left] == val) {
// 用右侧最后一个有效元素覆盖当前待删除元素
nums[left] = nums[right - 1];
right--; // 右指针左移,缩小待处理区间
} else {
left++; // 左指针右移,寻找下一个待删除元素
}
}
return left; // 左指针最终位置 = 有效元素个数
}
- 指针定义
left:从左向右遍历,寻找 等于val的待删除元素。right:从右向左收缩,标记待覆盖的有效元素 边界(初始为数组长度,right-1是最后一个元素索引)。
- 核心操作
- 当
nums[left] == val时,用nums[right-1]覆盖它,同时right--(相当于 "移除" 了一个待删除元素)。 - 当
nums[left] != val时,left++(当前元素有效,继续向后找)。
- 当
- 终止条件
left < right:当left == right时,左右指针相遇,所有待删除元素已被覆盖,循环结束。
- 返回值
left即为有效元素的个数 ,数组前left个元素为不等于val的结果。