返回
路飞的算法修炼之路:剑指 143. 重排链表
前端
2023-11-28 15:12:39
写在前面
大家好,我是路飞,一个热爱算法的前端摸鱼老。今天,我将与大家分享一道算法题 —— LeetCode 143. 重排链表。
这道题看似简单,实则暗藏玄机。为了让大家更好地理解重排链表的精妙之处,我将使用双指针技术,提供一种清晰易懂的解题思路。话不多说,让我们一起扬帆起航,踏上算法修炼的征途!
题目解析
题目:
给定一个单链表 L: L0 → L1 → … → Ln-1 → Ln ,将其重排为: L0 → Ln → L1 → Ln-1 → L2 → Ln-2 → …
示例:
给定链表:1->2->3->4,重排后得到:1->4->2->3。
思路导引
这道题的核心在于理解重排链表的本质。重排链表的目的是将链表中的偶数项(从 0 开始计数)全部移到奇数项的后面。
我们可以使用双指针技术来实现这一目标:
- 创建两个指针 :slow 和 fast,slow 指针每次移动一步,fast 指针每次移动两步。
- 当 fast 指针到达链表末尾时 ,slow 指针指向链表中点。
- 将 slow 指针指向的中点节点作为分界点 ,将链表拆分为两部分。
- 对后一部分链表进行逆置操作 。
- 将逆置后的后一部分链表插入到前一部分链表中 。
代码实现
def reorderList(self, head: Optional[ListNode]) -> None:
if not head or not head.next:
return
slow, fast = head, head.next
while fast and fast.next:
slow = slow.next
fast = fast.next.next
second = slow.next
prev = slow.next = None
while second:
nxt = second.next
second.next = prev
prev = second
second = nxt
first, second = head, prev
while second:
nxt1, nxt2 = first.next, second.next
first.next = second
second.next = nxt1
first, second = nxt1, nxt2
时间复杂度:
O(n),其中 n 为链表的长度。
空间复杂度:
O(1),因为我们没有使用额外的空间。
总结
通过使用双指针技术,我们可以轻松解决 LeetCode 143. 重排链表 这道算法题。理解重排链表的本质至关重要,它将引导我们找到最优的解题思路。
算法修炼之路漫漫其修远,希望这道题的讲解能帮助大家提升算法思维。让我们继续前行,不断探索算法的奥秘,提高逼格,成为一名合格的摸鱼老!
附录
拓展练习:
- 尝试使用递归的方法解决这道题。
- 如果链表中存在环,如何处理?
- 如何优化代码,使其时间复杂度达到 O(log n)?
参考链接: