【初級演算法】刪除排序數組中的重複項

刪除排序數組中的重複項

給你一個 升序排列 的數組 nums ,請你 原地 刪除重複出現的元素,使每個元素 只出現一次 ,返回刪除後數組的新長度。元素的 相對順序 應該保持 一致

由於在某些語言中不能改變數組的長度,所以必須將結果放在數組nums的第一部分。更規範地說,如果在刪除重複項之後有 k 個元素,那麼 nums 的前 k 個元素應該保存最終結果。

將最終結果插入 nums 的前 k 個位置後返回 k

不要使用額外的空間,你必須在 原地 修改輸入數組 並在使用 O(1) 額外空間的條件下完成。

判題標準:

系統會用下面的程式碼來測試你的題解:

int[] nums = [...]; // 輸入數組
int[] expectedNums = [...]; // 長度正確的期望答案

int k = removeDuplicates(nums); // 調用

assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
    assert nums[i] == expectedNums[i];
}

如果所有斷言都通過,那麼您的題解將被 通過

示例 1:

**輸入:**nums = [1,1,2]
**輸出:**2, nums = [1,2,_]
**解釋:**函數應該返回新的長度 **`2`** ,並且原數組 _nums_ 的前兩個元素被修改為 **`1`**, **`2`** `。`不需要考慮數組中超出新長度後面的元素。

示例 2:

**輸入:**nums = [0,0,1,1,1,2,2,3,3,4]
**輸出:**5, nums = [0,1,2,3,4]
**解釋:**函數應該返回新的長度 **`5`** , 並且原數組 _nums_ 的前五個元素被修改為 **`0`**, **`1`**, **`2`**, **`3`**, **`4`** 。不需要考慮數組中超出新長度後面的元素。

提示:

  • 0 <= nums.length <= 3 * 104
  • -104 <= nums[i] <= 104
  • nums 已按 升序 排列

題解

因為數組是排序的,只要是相同的肯定是挨著的,我們只需要遍歷所有數組,然後前後兩兩比較,如果有相同的就把後面的給刪除。

1,雙指針解決

使用兩個指針,右指針始終往右移動

  • 如果右指針指向的值等於左指針指向的值,左指針不動。
  • 如果右指針指向的值不等於左指針指向的值,那麼左指針往右移一步,然後再把右指針指向的值賦給左指針
//雙指針解決
public int removeDuplicates(int[] A) {
    //邊界條件判斷
    if (A == null || A.length == 0)
        return 0;
    int left = 0;
    for (int right = 1; right < A.length; right++)
        //如果左指針和右指針指向的值一樣,說明有重複的,
        //這個時候,左指針不動,右指針繼續往右移。如果他倆
        //指向的值不一樣就把右指針指向的值往前挪
        if (A[left] != A[right])
            A[++left] = A[right];
    return ++left;
}

或者還可以換一種解法,其實原理都是一樣的。

public int removeDuplicates(int[] A) {
    int count = 0;//重複的數字個數
    for (int right = 1; right < A.length; right++) {
        if (A[right] == A[right - 1]) {
            //如果有重複的,count要加1
            count++;
        } else {
            //如果沒有重複,後面的就往前挪
            A[right - count] = A[right];
        }
    }
    //數組的長度減去重複的個數
    return A.length - count;
}