1. 程式人生 >實用技巧 >其它 >【刷穿 LeetCode】19. 刪除連結串列的倒數第 N 個結點(中等)

【刷穿 LeetCode】19. 刪除連結串列的倒數第 N 個結點(中等)


技術標籤:刷穿 LeetCode演算法與資料結構LeetCode 題解連結串列演算法資料結構leetcode單鏈表

題目描述

給你一個連結串列,刪除連結串列的倒數第 n 個結點,並且返回連結串列的頭結點。

【刷穿 LeetCode】19. 刪除連結串列的倒數第 N 個結點(中等)


進階:你能嘗試使用一趟掃描實現嗎?

示例 1:

輸入:head = [1,2,3,4,5], n = 2
輸出:[1,2,3,5]

示例 2:

輸入:head = [1], n = 1
輸出:[]

示例 3:

輸入:head = [1,2], n = 1
輸出:[1]

提示:

  • 連結串列中結點的數目為 sz
  • 1 <= sz <= 30
  • 0 <= Node.val <= 100
  • 1 <= n <= sz

快慢指標解法

刪除連結串列的倒數第 n 個結點,首先要確定倒數第 n 個節點的位置。

我們可以設定兩個指標,分別為 slow 和 fast,剛開始都指向 head。

然後先讓 fast 往前走 n 步,slow 指標不動,這時候兩個指標的距離為 n。

再讓 slow 和 fast 同時往前走(保持兩者距離不變),直到 fast 指標到達結尾的位置。

這時候 slow 會停在待刪除節點的前一個位置,讓 slow.next = slow.next.next 即可。

但這裡有一個需要注意的邊界情況是:如果連結串列的長度是 L,而我們恰好要刪除的是倒數第 L 個節點(刪除頭節點),這時候 fast 往前走 n 步之後會變為 null,此時我們只需要讓 head = slow.next 即可刪除。

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        if (head.next == null) return null;

        ListNode slow = head;
        ListNode fast = head;
        while (n-- > 0) fast = fast.next;
            
        if (fast == null) {
            head = slow.next;
        } else {
            while (fast.next != null) {
                slow = slow.next;
                fast = fast.next;
            }
            slow.next = slow.next.next;
        }
        return head;
    }
}
  • 時間複雜度:需要掃描的長度為連結串列的長度。複雜度為 O ( n ) O(n) O(n)

  • 空間複雜度: O ( 1 ) O(1) O(1)


最後

這是我們「刷穿 LeetCode」系列文章的第 No.19 篇,系列開始於 2021/01/01,截止於起始日 LeetCode 上共有 1916 道題目,部分是有鎖題,我們將先將所有不帶鎖的題目刷完。

在這個系列文章裡面,除了講解解題思路以外,還會盡可能給出最為簡潔的程式碼。如果涉及通解還會相應的程式碼模板。

由於 LeetCode 的題目隨著周賽 & 雙週賽不斷增加,為了方便我們統計進度,我們將按照系列起始時的總題數作為分母,完成的題目作為分子,進行進度計算。當前進度為 19/1916 。

為了方便各位同學能夠電腦上進行除錯和提交程式碼,我建立了相關的倉庫:Github 地址 & Gitee 地址。

在倉庫地址裡,你可以看到系列文章的題解連結、系列文章的相應程式碼、LeetCode 原題連結和一些其他的優選題解。

#演算法與資料結構

#LeetCode題解

#演算法面試

【刷穿 LeetCode】19. 刪除連結串列的倒數第 N 個結點(中等)