【LeetCode】143. 重排链表

【2019年计算机统考408真题】

一、题目描述

给定一个单链表 L:L0→L1→…→Ln-1→Ln ,
将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→…

你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

示例 1:

给定链表 1->2->3->4, 重新排列为 1->4->2->3.

示例 2:

给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.

二、解题思路 & 代码

发现是由L摘取第一个元素,再摘取倒数第一个元素…依次合并成的。
为了方便链表后半段取元素,需要先将L后半段原地逆置,否则每取最后一个节点都需要遍历一次链表。
【408真题题目要求空间复杂度为O(1),不能借助栈】

步骤

  1. 先找处链表L的中间结点,为此设置两个指针p和q,指针p每次走一步,指针q每次走两步,当指针q到达链尾时,指针p正好在链表的中间结点;
  2. 然后将L的后半段结点原地逆置;
  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: ListNode) -> None:
        """
        Do not return anything, modify head in-place instead.
        """
        if not head or not head.next or not head.next.next:
            return

        slow, fast = head, head.next
        while fast and fast.next:
            slow, fast = slow.next, fast.next.next
        new_head = slow.next
        slow.next = None

        new_head = self.revserve_list(new_head)

        while new_head:
            post = new_head.next
            new_head.next = head.next
            head.next = new_head
            head = new_head.next
            new_head = post

    def revserve_list(self, head):
        if not head or not head.next:
            return head

        prev = None
        while head:
            post = head.next
            head.next = prev
            prev = head
            head = post
        return prev

时间复杂度: O(n)

参考:

  1. LeetCode 题解讨论区

猜你喜欢

转载自blog.csdn.net/weixin_41888257/article/details/108365618