这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战
难度:中等
题目描述
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:
输入:head = [1,2,3,4] 输出:[2,1,4,3]
示例 2:
输入:head = [] 输出:[]
示例 3:
输入:head = [1] 输出:[1] 提示:
链表中节点的数目在范围 [0, 100] 内 0 <= Node.val <= 100
思路一:递归
-
令newHead为新头节点,则head为旧头节点
-
剩余链表的旧头节点是newHead.next,将其作为递归的参数,也就是递归中的“head”。
-
令head.next = 递归后的newHead,令newHead.next = head。
-
返回新链表的头节点newHead
-
下面以 1 → 2 → 3 → 4 → 5 → 6 为例画了整个递归的过程
-
在递归前进时其实就是head和newHead在两步两步的挪动,直到挪到了空位
-
递归返回时就是将前一层递归的head指向了后一层递归的newHead,然后将该层的newHead指向head
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
newHead = head.next
head.next = self.swapPairs(newHead.next)
newHead.next = head
return newHead
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(n)
思路二:迭代
- 创建新的节点 dmy,令其指向head,也就是在原链表前加入了一个虚拟节点。
- 用tmps表示当前到达的节点。只要tmps后面至少有两个节点(node1&node2),循环继续。
- 循环内容(就是交换两个节点)
- i. tmps指向node2
- ii. node1指向剩余链表的头节点node2.next
- iii. node2指向node1
- iv. 挪动tmps、node1、node2
- 返回dmy.next
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
dmy = ListNode()
dmy.next = head
tmp = dmy
while tmps.next and tmps.next.next:
node1 = tmps.next
node2 = node1.next
tmps.next = node2
node1.next = node2.next
node2.next = node1
tmps = node1
return dmy.next
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(1)