原文題目
Given a linked list, swap every two adjacent nodes and return its head. You must solve the problem without modifying the values in the list's nodes (i.e., only nodes themselves may be changed.)
題目摘要
Example 1:
Input: head = [1,2,3,4]
Output: [2,1,4,3]
Explanation:
Example 2:
Input: head = []
Output: []
Example 3:
Input: head = [1]
Output: [1]
Example 4:
Input: head = [1,2,3]
Output: [2,1,3]
解題思路
dummy
節點,其值為 0,並將其 next
指向鏈結串列的頭節點。這樣做是為了方便處理可能會涉及到修改頭節點的情況(如當頭節點被交換時)。pre
指標用來指向每次進行交換的前一個節點,初始指向 dummy
。這樣確保我們能夠順利地將節點連接回已經處理的部分。while
迴圈檢查當前是否還有兩個節點可以進行交換(即 pre.next
和 pre.next.next
都不為 null)。first
指向當前需要交換的第一個節點 (pre.next
),將 second
指向當前需要交換的第二個節點 (pre.next.next
)。first.next
指向 second.next
,即跳過第二個節點,連接到下一個節點。second.next
指向 first
,這樣第一和第二個節點就完成了相鄰交換。pre.next
指向 second
,這樣 pre 節點與新的第一個節點相連。pre
更新為 first
,以準備交換下一對節點。dummy.next
,即新的頭節點。程式碼
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode(0); //設立一個dummy節點
dummy.next = head; //dummy.next指向頭節點
ListNode pre = dummy;//pre是指向每次交換的前一個節點
//當前還有兩個節點可以進行交換時進行操作
while (pre.next != null && pre.next.next != null) {
ListNode first = pre.next; //first是當前需要交換的第一個節點
ListNode second = pre.next.next; //second是當前需要交換的第二個節點
// 進行交換
first.next = second.next;
second.next = first;
pre.next = second;
//更新pre,繼續處理下一對節點
pre = first;
}
return dummy.next; //回傳新的頭節點
}
}
結論
這題我使用一個 dummy
節點來有效簡化邊界條件的處理,尤其是在交換涉及到鏈結串列的頭節點時。這樣我們不僅可以隨意地交換任何兩個節點,也能確保在進行交換後,所有節點的鏈結正確無誤。在遍歷過程中,透過 pre
指標追蹤每次交換的前一個節點,這樣不論是單獨的節點還是整個鏈結串列,都能順利地進行節點的連接。了解三個節點如何進行交換後,調整它們的鏈結順序,最後更新 pre
指標,以準備進行下一次的交換。整個過程中,我們不斷重複這些操作,直到所有相鄰節點都完成交換。