24. 两两交换链表中的节点
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
方法一、递归
首先定义递归终止条件:
- head.next不存,代表链表结束了
- head.next.next不存在,表示不能两两配对
Swift
func swapPairs(_ head: ListNode?) -> ListNode? {
//递归实现,抽象
//终止条件就是当结束or只剩一个时,终止
if head == nil || head?.next == nil {
return head
}
let newHead:ListNode? = head?.next
head?.next = swapPairs(newHead?.next)
newHead?.next = head
return newHead
}
OC
- (ListNodeOC * _Nullable)swapPairs:(ListNodeOC * _Nullable)head {
//递归终止条件
if (!head.next || !head.next.next) {
return head
}
ListNodeOC *freshHead = [ListNodeOC alloc] initWithVal:0];
while(head.next && head.next.next) {
head.next = swapPairs(freshHead.next);
freshHead.next = head;
}
return freshHead;
}
方法二、迭代
用到了解决链表问题的三把斧:哑巴节点、栈、前后指针,用tempNode标记,按步进为2向后迭代,依次两两交换
Swift
func swapPairs(_ head: ListNode?) -> ListNode? {
//哑巴节点
let dummyNode = ListNode(0)
dummyNode.next = head;
var tempNode:ListNode? = dummyNode
while tempNode?.next != nil && tempNode?.next?.next != nil {
let fir = tempNode?.next
let sec = tempNode?.next?.next
//1->3
fir?.next = sec?.next
//2->1
sec?.next = fir
//temp->next -> sec
tempNode?.next = sec
//update tempNode pointer
tempNode = fir
}
return dummyNode.next
}
OC
- (ListNodeOC * _Nullable)swapPairs:(ListNodeOC * _Nullable)head {
//build dummy node
ListNodeOC *dummyNode = [[ListNodeOC alloc] initWithVal:0];
dummyNode.next = head;
ListNodeOC *tempNode = dummyNode;
while(tempNode.next && tempNode.next.next) {
ListNodeOC *fir = tempNode.next;
ListNodeOC *sec = tempNode.next.next;
tempNode.next = sec;
fir.next = sec.next;
sec.next = fir;
tempNoe = fir;
}
return dummyNode.next;
}