LeetCode 143. Reorder List - 链表(Linked List)系列题14

You are given the head of a singly linked-list. The list can be represented as:

L0 → L1 → … → Ln - 1 → Ln

Reorder the list to be on the following form:

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

You may not modify the values in the list's nodes. Only nodes themselves may be changed.

Example 1:

Input: head = [1,2,3,4]
Output: [1,4,2,3]

Example 2:

Input: head = [1,2,3,4,5]
Output: [1,5,2,4,3]

Constraints:

  • The number of nodes in the list is in the range [1, 5 * 104].
  • 1 <= Node.val <= 1000

题目要求重组一个链表,把链表节点从中间分成前后两个部分,把后半部分的节点颠倒顺序,然后挨个插入前半部分每两个节点之间。根据题意,解题思路跟LeetCode 86. Partition List 有点类似,都是先把链表分成两部分然后按一定规则再合并成一个链表。

1)将链表从中间节点分成两部分,可以利用快慢指针来找中间节点,快指针一次走两步慢指针一次走一步,当快指针走到尾部不能再走时,慢指针指向的节点就是中间节点(对于节点个数是偶数的链表,中间有两个节点,慢指针指向的是两个中的第二个,但这不影响处理)。找到中间节点后就把链表分成了两部分:从头节点到中间节点,从中间节点到尾节点。

2)反转链表的第二部分即反转从中间节点到尾节点。可参考LeetCode 206. Reverse Linked List

注意两部分都含有中间节点,反转后中间节点的next指向了空节点,实际上该中间节点就是最后合并后的新链表的尾节点,刚好它的next需要指向空。

3)把第二部分的节点插入第一部分的间隔中。注意,由于反转后的第二部分的最后一个节点也就是中间节点已经在第一部分了末尾了,所以不需要处理可作为终止判断条件。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reorderList(self, head: Optional[ListNode]) -> None:
        """
        Do not return anything, modify head in-place instead.
        """
        if not head or not head.next:
            return
        
        slow, fast = head, head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
        
        pre, cur = None, slow
        while cur:
            tmp = cur.next
            cur.next = pre
            pre = cur
            cur = tmp
        
        p1, p2 = head, pre
        while p2.next:
            tmp = p2.next
            p2.next = p1.next
            p1.next = p2
            p1 = p2.next
            p2 = tmp

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值