【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),不能借助栈】
步骤
- 先找处链表L的中间结点,为此设置两个指针p和q,指针p每次走一步,指针q每次走两步,当指针q到达链尾时,指针p正好在链表的中间结点;
- 然后将L的后半段结点原地逆置;
- 从单链表前后两段中 依次各取一个结点,按要求重排;
后半段逆置那里搞不懂的可以去看看力扣有一道题 反转链表
另外这个题与判断 回文链表 那一题所用的方法一样,一块整理着学习效果不错
# 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)