題目描述
給你一個有序數組?nums
?,請你?原地?刪除重復出現的元素,使得出現次數超過兩次的元素只出現兩次?,返回刪除后數組的新長度。
不要使用額外的數組空間,你必須在?原地?修改輸入數組?并在使用 O(1) 額外空間的條件下完成。
題目解法
使用了??快慢指針??:
- 快指針 (fast)??:遍歷整個數組。
- ??慢指針 (slow)??:指向下一個有效元素(即允許保留的元素)應該存放的位置,其最終值就是新數組的長度。
??核心邏輯??:對于當前快指針 fast指向的元素,檢查它是否與 nums[slow - 2]相同。如果??不同??,說明這個元素(例如 nums[fast])的出現次數還沒有達到兩次,可以保留,于是將其復制到 slow的位置,然后 slow前進一步。
這里有個問題是為什么nums[fast]和nums[slow - 2]比較呢?
慢指針 slow不僅指向下一個待插入位置,其前方的區域([0, slow-1])已經是處理好的、滿足每個元素最多出現兩次要求的“新數組”。??nums[slow - 2]代表了“新數組”中當前正在檢查的元素的“上一次可能重復”的位置??。
更詳細的說明下:由于數組有序,如果 nums[fast](當前遍歷到的元素)與 nums[slow - 2](新數組中的前一個相同元素)相等,意味著如果放入 nums[slow],就會導致 nums[slow - 2], nums[slow - 1]和 nums[slow]三個連續相同的元素,這違反了“最多出現兩次”的規則。因此,只有不相等時才能放入。
class Solution {public int removeDuplicates(int[] nums) {if (nums.length <= 2) {return nums.length;}int slow = 2;for (int fast = 2; fast < nums.length; fast++) {if (nums[fast] != nums[slow - 2]) {nums[slow] = nums[fast];slow++;}}return slow;}
}