🧠 要求保持相对顺序原地修改,且要”删除/筛选/移动”元素

一句话结论:
👉 四个问题:结构变不变(判断是否适用),什么情况可以保留,slow,fast
快慢指针的核心不在于“删除”,而在于**“保留”**。 思路逆转:不要管哪些元素要删掉,只关心 “哪些元素应该被保留”,并把它们按照顺序用 slow 指针重组在数组的前缀区。 返回值意义:slow 的值定义了“有效区间 [0, slow)”,区间之外的数据在算法语义上等同于“不存在”,无需物理删除。

⭐ 模板

  1. slow:始终指向“下一个合法元素应该放置的位置”
    int slow = 0;

  2. fast:遍历整个数组
    for (int fast = 0; fast < nums.length; fast++) {
    // 核心判断:当前 fast 指向的元素,是我们需要保留的吗
    if ( 满足保留条件 ) {
    nums[slow] = nums[fast];
    slow++;
    }
    }

  3. slow 的值正好就是新数组的长度
    return slow;

Questions

① 结构变不变?

❌ 不新建数组

✅ 通常要求保持剩余元素的「相对顺序」

✅ 原地修改

👉 满足 ⇒ 快慢指针

② 什么情况下「可以保留」?

👉 哪些元素,应该被放到数组前面?

③ slow 是谁?

slow 永远表示:下一个“合法元素”应该放的位置

相关练习题

1. LeetCode 27. 移除元素

题意: 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。

2. LeetCode 26. 删除有序数组中的重复项

题意: 给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。

3. LeetCode 80. 删除有序数组中的重复项 II

题意: 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。

Tips:通用去重模板(保留 k 位):

1
2
3
4
if (slow < k || nums[fast] != nums[slow - k]) {
nums[slow] = nums[fast];
slow++;
}