LeetCode#26 | Remove Duplicates from Sorted Array 刪除有序數組中的重複元素

一、題目

Given a sorted array, remove the duplicates in-place such that each element appear only once and return the new length.
Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
Example 1:

Given nums = [1,1,2],
Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively.
It doesn't matter what you leave beyond the new length.

Example 2:
Given nums = [0,0,1,1,1,2,2,3,3,4],
Your function should return length = 5, with the first five elements of nums being modified to 0, 1, 2, 3, and 4 respectively.
It doesn't matter what values are set beyond the returned length.

刪除有序數組中的重複元素
給定一個排序數組,在原地刪除重複出現的元素,使得每個元素只出現一次,返回移除後數組的新長度。
不要使用額外的數組空間,必須在原地修改輸入數組,並使用 O(1) 額外空間來修改輸入的數組。
第一個示例中,函數應該返回新的長度 2, 並且原數組 nums 的前兩個元素被修改爲 1, 2。
第二個示例中,函數應該返回新的長度 5, 並且原數組 nums 的前五個元素被修改爲 0, 1, 2, 3, 4。
這裏不需要考慮數組中超出新長度後面的元素。

二、題解

  • 首先,題目規定了空間複雜度是O(1),對時間複雜度沒做要求,當然了,我們解題還是要追求一下更小的時間複雜度,能O(n)就不O(n²),能O(logn)就不O(n)。

  • 其次,題目給出數組已經排好序了,當數組爲空或只有1個元素時,肯定沒有重複項,直接返回數組長度即可;只有當數組中的元素大於3個,纔可能出現重複項。

  • 第三,要修改給定的數組,而不是返回一個新數組,我想到了PHP中的“引用傳遞”,修改數組中的某個元素,整個數組也會變化。

我首先想到的做法是:遍歷數組,將當前元素和下一個元素進行比較,如果相同,就刪除當前元素,直到遍歷到末尾。代碼如下:

function removeDuplicates(&$nums) {
    if (count($nums) <= 2) {
        return count($nums);
    }

    for ($i = 0; $i < count($nums) - 1; $i++) {
        if ($nums[$i] == $nums[$i + 1]) {
            unset($nums[$i]);
        }
        echo count($nums) . "<br>";
    }
    return count($nums);
}

提交代碼未通過。輸入的是[0,0,1,1,1,2,2,3,3,4],可輸出的是[0,1,2,3,3,4],並沒有完成去重。琢磨了一下代碼,發現漏洞:既然是引用傳遞,每 unset 一個元素,都會改變數組的長度,而隨着數組長度的縮短,遍歷次數也會跟着改變(減少),後面的元素就不再進行比較、刪除了。

那就記錄遍歷時遇到的重複元素,使用兩個指針,一快一慢指針,慢指針 i 記錄不重複元素,快指針 j 遍歷數組,當(nums[i] != nums[j])時,將慢指針右移一位,同時將快指針指向的元素賦值給當前慢指針;當兩者相等時則跳過,即雙指針法

function removeDuplicates(&$nums) {
    if (count($nums) <= 1) {
        return count($nums);
    }

    $i = 0;
    for ($j = 1; $j < count($nums); $j++) {
        if ($nums[$i] == $nums[$j]) {
            continue;
        }
        $i++;
        $nums[$i] = $nums[$j];
    }
    return count(array_slice($nums, 0, $i + 1));
}

三、執行結果

解法 執行用時 內存消耗
雙指針法 28 ms 16.8 MB
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章