1. 程式人生 > 實用技巧 >每日一道 LeetCode (18):刪除排序連結串列中的重複元素

每日一道 LeetCode (18):刪除排序連結串列中的重複元素

每天 3 分鐘,走上演算法的逆襲之路。

前文合集

每日一道 LeetCode 前文合集

程式碼倉庫

GitHub: https://github.com/meteor1993/LeetCode

Gitee: https://gitee.com/inwsy/LeetCode

題目:刪除排序連結串列中的重複元素

題目來源:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/

給定一個排序連結串列,刪除所有重複的元素,使得每個元素只出現一次。

示例 1:

輸入: 1->1->2
輸出: 1->2

示例 2:

輸入: 1->1->2->3->3
輸出: 1->2->3

解題思路

連續被數學題虐了兩天,今天終於能看到一道正常的,普通智商可以解開的演算法題了。

我太難了,每天晚上都被數學題虐的死去活來,一度讓我精神恍惚,彷彿回到高三那一年。

題目要求給一個排序連結串列去重,這個連結串列已經是排好序的了,那麼去重這件事兒就很簡單了,只要重複,必定連結串列上的兩個元素是相鄰的,所以只需要在一個迴圈中判斷相鄰 nn + 1 個元素是否相等就好,如果相等的話,那麼元素 n 上的指標直接指向 n + 2 ,進行下一次迴圈,判斷這兩個元素是否相等。

public ListNode deleteDuplicates(ListNode head) {
    ListNode current = head;
    while (current != null && current.next != null) {
        if (current.val == current.next.val) {
            current.next = current.next.next;
        } else {
            current = current.next;
        }
    }
    return head;
}

上面這種演算法稍稍有點小問題,從示意圖上可以看到, n + 1 這個元素的指標還指向了 n + 2 ,如果連結串列比較大,會產生很多的 「野指標」 ,這段程式碼稍微改一下,我們把刪掉不用的元素置空:

public ListNode deleteDuplicates_1(ListNode head) {
    ListNode current = head;
    while (current != null && current.next != null) {
        if (current.val == current.next.val) {
            ListNode node = current.next;
            current.next = node.next;
            node.next = null;
        } else {
            current = current.next;
        }
    }
    return head;
}

和第一種寫法耗時維持一致,這個很正常,我們只是清除掉了不在使用的元素,並沒有優化尋找方案,整體的時間複雜度還是保持了 O(n) 。