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)