Skip to main content

143.重排链表

标签: linked-list, two-pointers

难度: Medium

通过率: 60.93%

原题链接: https://leetcode.com/problems/reorder-list/description/

题目描述

给定一个单链表的头节点,链表形式如下:

L0 → L1 → … → Ln - 1 → Ln

重排链表为如下形式:

L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …

你不能修改链表节点中的值,只能调整节点本身的位置。

解题思路

解决这个问题可以通过以下几个步骤实现:

  1. 寻找中间节点: 使用快慢指针找到链表的中间节点。快指针每次前进两个节点,慢指针每次前进一个节点,当快指针到达末尾时,慢指针恰好在中间节点的位置。

  2. 反转后半部分链表: 从中间节点出发,反转链表后半部分。我们可以通过迭代的方式反转链表。

  3. 交替合并链表: 将前半部分和经过反转的后半部分交替合并,得到最终结果。通过遍历两个链表,分别取一个节点加入到新链表中。

通过这三步就可以实现链表的重排。

代码实现

class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next

class Solution:
def reorderList(self, head: ListNode) -> None:
"""
Do not return anything, modify head in-place instead.
"""
if not head or not head.next:
return

# step 1: find the middle of the list
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next

# step 2: reverse the second half of the list
prev, curr = None, slow.next
slow.next = None # split the list into two parts
while curr:
next_node = curr.next
curr.next = prev
prev = curr
curr = next_node

# step 3: merge both halves
first, second = head, prev
while second:
tmp1 = first.next
tmp2 = second.next
first.next = second
second.next = tmp1
first = tmp1
second = tmp2

复杂度分析

时间复杂度为 O(n)O(n),其中 nn 是链表中的节点数量,因为我们遍历了链表几次。

空间复杂度为 O(1)O(1),因为我们只使用了常数个额外的节点指针进行操作。