這是一道鏈結串列(Linked List)問題,要求從鏈結串列的尾部算起,移除第 n 個節點,並回傳新的鏈結串列的頭部。
這道題目的核心在於,通常只能從鏈結串列的頭部開始向前遍歷,但在遍歷到某個節點時,我們並不知道它距離尾部還有多遠。例如:如果要移除倒數第2個節點,當遍歷到節點3時,並不知道後面還有4,5兩個節點。當遍歷到節點4時,才會知道後面只剩5一個節點。要移除一個節點,需要找到它前一個節點,然後將前一個節點的next指向要移除節點的next節點。
目標: 在一次遍歷中,找到「倒數第n個節點」的前一個節點。
要在一趟中完成,可以利用兩個指標(或稱指針),它們之間保持一個固定的間距。這種方法也常被稱為快慢指標法,但在這題中,更著重於它們之間的間距。
這題的解題思路是先創建虛擬頭節點(Dummy Node):為了處理邊界情況,特別是當要移除的節點是頭節點時(即 n = sz 的情況),需要一個虛擬頭節點(通常取名為 dummy)。dummy 節點指向鏈結串列的實際頭節點 head。這樣,即使 head 被移除,我們也能透過 dummy.next 取得新的頭部。
再來,設置間距n:使用一個快指標(fast)和一個慢指標(slow)。先讓快指標 fast 從 dummy 節點開始,向前移動 n + 1 步。至於為什麼是n + 1步?為了讓fast走到鏈結串列末尾時,slow剛好停在倒數第n個節點的前一個節點。如果n是指倒數第n個節點,那麼倒數第n個節點距離末尾有n − 1步。因此,讓fast比 slow多走n步,當fast走到末尾時,slow剛好在倒數第n個節點。但要移除倒數第n個節點,所以需要找到它的前一個節點。這意味著fast必須比slow多走n + 1步(或讓slow距離倒數第n個節點的距離為1)。一個更簡單的理解是:讓fast和slow都從dummy開始。先讓fast走n步。現在fast和 slow之間有n個節點的間隔。接著,讓fast和slow同時向前走,直到fast走到鏈結串列的末尾(即 fast.next == null)。此時,因為兩者間隔固定為n步,slow 就會停在倒數第n個節點的前一個節點。
接著是同時移動並移除:當fast走到null(或 fast.next 走到null,取決於你的起點和步數設定),停止遍歷。此時slow節點就是要尋找的「要移除節點的前一個節點」。執行移除操作:slow.next = slow.next.next;
最後,回傳結果:回傳dummy.next,這就是新的鏈結串列的頭部。