兩兩交換連結串列中的節點
給定一個連結串列,兩兩交換其中相鄰的節點,並返回交換後的連結串列。
你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。
思路
這裡還是要應用虛擬頭節點,不然交換連結串列頭節點的操作會與交換其他節點時不同
交換的過程其實不難理解,但是程式碼實現過程需要注意很多細節
下面是交換過程的圖解
首先,定義一個虛擬頭節點
並讓當前指標cur指向dummy head【注意:cur一定要在需要操作的兩個節點之前】
然後按途中順序將對應節點的next指好即可
注意:雖然畫圖我們很好理解,但是在操作過程中有很多細分步驟,如果直接上手寫程式碼會很困惑
例如,當dummy指向節點2(也就是cur.next.next)後,dummy與原來的節點1就斷開連線了
此時再想透過cur去尋找到節點1(cur.next)就行不通了,進而節點2也就無法指向節點1,步驟②無法繼續進行
與翻轉連結串列時類似,我們需要一個臨時節點temp先去儲存節點1
讓節點2透過指向temp的方式找到節點1
ps:為什麼不存節點2?因為步驟①之後節點2就已經是cur.next了,而dummy是不會變的,所以怎麼都能找到節點2
當節點2指向temp(儲存有cur.next)後,節點2與原來的節點3就斷開連線了
同理,我們應該把節點3也用臨時節點儲存,這裡用temp1儲存
於是節點2指向節點3的過程就變成了:
temp1是節點3的備份,它後面還是和節點4連著,所以不用擔心找不到節點4
至此,節點1與節點2完成了交換,cur移動到cur.next.next(即交換後此處為節點1,是什麼節點並不重要,反正待會交換的又不是當前cur指向的節點,而是後兩個節點),展開後的結果如下:
連結串列節點數為奇數時,結束條件:cur.next.next = null
連結串列節點數為偶數時,結束條件:cur.next = null
程式碼
思路透過畫圖可以很好理解,但是程式碼實現又有很多坑
class Solution {
public ListNode swapPairs(ListNode head) {
//定義虛擬頭節點
ListNode dummy = new ListNode(0);
dummy.next = head;//虛擬頭節點指向head
ListNode cur = dummy;
//定義臨時節點用於儲存節點1、3
ListNode temp;
ListNode temp1;
//遍歷連結串列
//注意這裡的結束條件,連結串列節點數為奇偶情況下是不同的
//需要先驗證cur.next再驗證cur.next.next
//要不然如果是偶數個節點你先驗cur.next.next直接就空指標異常了
while(cur.next != null && cur.next.next != null ){
//這裡下意識肯定就想開始交換了,但如果不先儲存節點就會出現空指標異常
temp = cur.next;
temp1 = cur.next.next.next;
cur.next = cur.next.next;//dummy換2
cur.next.next = temp;//2換1
cur.next.next.next = temp1;//1換3
cur = cur.next.next;//移動cur至新的待交換的兩個節點前
}
//遍歷結束,返回dummy的下一個節點即可
return dummy.next;
}
}
易錯點:
1、建立完dummy後記得指向head
2、交換過程中要以cur為參照點來表示參與交換的節點,不要變,例如1換3時不能寫成
`temp.next = temp1;