返回
解剖 Leetcode 24:巧妙交换,重塑单向循环流转
前端
2023-09-30 10:00:22
问题概述
给定一个单向循环流转的节点,你的任务是两两交换其相邻节点,并返回交换后的循环流转的节点。请注意,你不可以直接修改节点值,而需要实际进行节点交换操作。
哨兵巧思
直观地,我们可以采用暴力法,对相邻节点逐一交换。然而,这种方法需要遍历整个循环流转的节点,在最坏情况下复杂度达到 O(n),其中 n 为节点数量。
聪明的算法设计者们引入了一个巧妙的概念:哨兵。哨兵是一个虚拟的节点,它指向第一个有效节点,且其 next 指针指向最后一个有效节点。有了哨兵,我们可以轻松地实现两两交换操作,因为我们只需要处理哨兵的 next 指针即可。
算法流程
以下是算法的详细流程:
- 初始化哨兵: 建立一个哨兵节点,使其指向第一个有效节点,并将其保存为头指针。
- 循环遍历: 以哨兵为起点,遍历整个循环流转的节点。
- 交换相邻节点: 对于每个节点,将其与后继节点交换。
- 更新头指针: 将哨兵的 next 指针更新为交换后的第一个节点。
- 终止条件: 当哨兵的 next 指针指向第一个有效节点时,算法结束。
代码实现
def swapPairs(head):
if not head or not head.next:
return head
dummy = ListNode(0)
dummy.next = head
prev = dummy
current = head
while current and current.next:
nextPair = current.next.next
second = current.next
prev.next = second
current.next = nextPair
second.next = current
prev = current
current = nextPair
return dummy.next
复杂度分析
在最坏情况下,算法需要遍历整个循环流转的节点,因此时间复杂度为 O(n)。空间复杂度为 O(1),因为我们只引入了一个哨兵节点。
总结
两两交换单向循环流转的节点问题,看似复杂,但通过巧妙的哨兵设计,我们可以将其简化为对哨兵 next 指针的巧妙操作。这体现了算法设计中的灵活思维,通过引入一个虚拟的哨兵节点,可以简化问题,提高算法效率。