24.兩兩交換鏈表中的節點
//給定一個鏈表,兩兩交換其中相鄰的節點,並返回交換後的鏈表。 // // 你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。 // // // // 示例: // // 給定 1->2->3->4, 你應該返回 2->1->4->3. // // Related Topics 鏈表
1.遞歸
thinking: 使用遞歸的方法 每一次遞歸都交換一對節點,用firstNode.next 記錄上一次節點交換後的首節點。secondNode節點作爲首節點。
public ListNode swapPairs(ListNode head) {
//if the list has no node or has only one node left
if(head == null || head.next == null){
return head;
}
//Nodes to be swapped
ListNode firstNode = head;
ListNode secondNode = head.next;
//swapping
firstNode.next = swapPairs(secondNode.next);
secondNode.next = firstNode;
//Now the head is the second node
return secondNode;
}
-
時間複雜度:O(N) O(N),其中 N 指的是鏈表的節點數量。
-
空間複雜度:O(N) O(N),遞歸過程使用的堆棧空間。
遞歸-簡潔版
public ListNode swapPairs(ListNode head) {
if ((head == null)||(head.next == null))
return head;
ListNode n = head.next;
head.next = swapPairs(head.next.next);
n.next = head;
return n;
}
2.迭代法
thinking:定義一個前驅節點,記錄每次交換後的節點變化
head節點和pre節點每次交換完成後重置。
/***
* 迭代法
* 1.定義一個前驅節點,用以記錄每次交換後的元素的前置節點
* 2.交換
* 3.head 節點 和pre節點重置
* @param head
* @return
*/
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode pre = dummy;
while ((head!=null) && (head.next !=null)){
ListNode firstNode = head;
ListNode secondNode = head.next;
//swap
pre.next = secondNode;//-1 -> 2
firstNode.next = secondNode.next;// 1 -> 3
secondNode.next = firstNode;
pre = firstNode;
head = firstNode.next;
}
return dummy.next;
}
-
時間複雜度:O(N),其中 N 指的是鏈表的節點數量。
-
空間複雜度:O(1)