返回

调整链表位置的巧妙方法:LeetCode 143 题重排链表解析

前端

题目解析:

    LeetCode 143 题要求我们对一个给定的单链表进行重排,使其满足以下条件:

    * 原链表的第一个节点 L0 应与最后一个节点 Ln 相邻
    * 原链表的第二个节点 L1 应与倒数第二个节点 Ln - 1 相邻
    * 原链表的第三个节点 L2 应与倒数第三个节点 Ln - 2 相邻
    * ...
    * 原链表的第 n 个节点 Ln 应与第一个节点 L0 相邻

    举例来说,对于链表 [1,2,3,4,5],重排后将变成 [1,5,2,4,3]。

    ### 算法思路:

    为了解决这个问题,我们可以采用一种巧妙的算法:

    1. 将链表分为两部分:前半部分和后半部分。
    2. 翻转后半部分的链表。
    3. 将前半部分和后半部分的链表交替合并。

    具体步骤如下:

    1. 使用快慢指针法将链表分为两部分。快指针一次走两步,慢指针一次走一步。当快指针到达链表的末尾时,慢指针恰好位于链表的中间。
    2. 将后半部分的链表翻转。我们可以使用递归或迭代的方法来实现链表翻转。
    3. 将前半部分和后半部分的链表交替合并。我们可以使用两个指针,分别指向前半部分和后半部分的链表的头结点。然后,我们将两个指针交替移动,并将指向的节点依次连接起来。

    ### Python 实现:

    ```python

def reorderList(head):
# 如果链表为空或只有一个节点,则直接返回
if not head or not head.next:
return

# 将链表分为两部分
slow = fast = head
while fast and fast.next:
    slow = slow.next
    fast = fast.next.next

# 翻转后半部分的链表
prev = None
while slow:
    nxt = slow.next
    slow.next = prev
    prev = slow
    slow = nxt

# 将前半部分和后半部分的链表交替合并
first = head
second = prev
while second:
    nxt1 = first.next
    nxt2 = second.next

    first.next = second
    second.next = nxt1

    first = nxt1
    second = nxt2

测试代码

head = ListNode(1)
head.next = ListNode(2)
head.next.next = ListNode(3)
head.next.next.next = ListNode(4)
head.next.next.next.next = ListNode(5)

reorderList(head)

打印重排后的链表

curr = head
while curr:
print(curr.val, end=" ")
curr = curr.next


        ### 总结:

        通过这篇文章,我们学习了解决 LeetCode 143 题:重排链表的方法。我们从题目的解析开始,一步步分析问题并提出解决办法,最后提供了一个简洁易懂的 Python 实现方案。希望这篇文章对大家理解链表重排的技巧有所帮助。