題目描述
給定一個鏈表,兩兩交換其中相鄰的節點,並返回交換後的鏈表。
你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。
示例:
給定 1->2->3->4, 你應該返回 2->1->4->3.
題目解析
方法一:遞歸
解題思路
遞歸的解題思路在於把子問題交給下一層遞歸函數處理,而本身只聚焦於本層次的問題,當你得到遞歸函數返回值時,默認爲已經得到正確結果,只需要繼續處理當前層邏輯即可。
本題需要兩兩交換鏈表節點,所以頭節點 head 的下一個節點 next 必然就是新的頭節點 newHead ,然後通過遞歸的方式交換 next 節點後面的鏈表,得到後續鏈表交換節點後直接賦值給頭節點 head 的next指針,處理 newHead 和 head 的關聯,得到交換後的鏈表。
代碼示例
Java:
/**
* Definition for singly-linked list.
*/
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
public ListNode swapPairs(ListNode head) {
// terminator
if (head == null || head.next == null) {
return head;
}
// recursion
ListNode newHead = head.next;
head.next = swapPairs(newHead.next);
// process data
newHead.next = head;
return newHead;
}
複雜度分析
時間複雜度:O(n)
空間複雜度:O(n),在遞歸時使用額外棧空間。
方法二:迭代
解題思路
迭代的方式大家都比較熟悉,從鏈表頭節點開始遍歷然後兩兩交換節點。在交換節點的過程中,需要注意就是鏈表遍歷到什麼位置了,兩兩節點交換完成後是否還能繼續向後遍歷。
迭代解法中通過 prev 和 curr 指針用來記錄鏈表當前遍歷位置,並且在兩兩節點交換完成後 prev 和 curr 指針向後移動繼續進行節點交換,直到鏈表末尾。
代碼示例
Java:
/**
* Definition for singly-linked list.
*/
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
public ListNode swapPairs(ListNode head) {
ListNode newHead = new ListNode(0);
newHead.next = head;
ListNode prev = newHead, curr = head;
while(curr != null && curr.next != null) {
// 記錄當前節點的next節點
ListNode next = curr.next;
// 交換節點
curr.next = curr.next.next;
next.next = curr;
prev.next = next;
// prev,curr指針後移
prev = curr;
curr = curr.next;
}
return newHead.next;
}
複雜度分析
時間複雜度:O(n)
空間複雜度:O(1)