问题
https://leetcode-cn.com/problems/reorder-list/
给定一个单链表 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.
思路
首先观察重排以后的链表,会发现是头尾交替连接的
那么我们可以当作是两个链表的交叉合并
给定链表 1->2->3->4, 重新排列为 1->4->2->3
要合并的这两个链表其中一个是链表的前半部分,另一个是链表后半部分的反转
这样我们就把问题转化成几个子问题:找到链表的中间节点,对后半部分的链表进行反转、合并两个链表
时间复杂度:O(n)
空间复杂度:O(1)
程序
# Definition for singly-linked list.# class ListNode:# def __init__(self, val=0, next=None):# self.val = val# self.next = nextclass Solution:def reorderList(self, head: ListNode) -> None:"""Do not return anything, modify head in-place instead."""dummy = ListNode(0)dummy.next = head# 找到中间节点low = dummyfast = dummywhile fast and fast.next:low = low.nextfast = fast.next.nextmid = low.nextlow.next = None# 反转mid = self.reverse(mid)# 交叉合并两个链表self.merge_two_list(dummy.next, mid)# 反转链表def reverse(self, head: ListNode) -> ListNode:if not head:return Nonecur = Nonewhile head:node = head.nexthead.next = curcur = headhead = nodereturn cur# 交叉合并两个链表def merge_two_list(self, l1: ListNode, l2: ListNode) -> ListNode:dummy = ListNode(0)cur = dummywhile l1 and l2:# 先连 l1cur.next = l1cur = cur.nextl1 = l1.next# 再连 l2cur.next = l2cur = cur.nextl2 = l2.next# 对剩下的部分进行单独处理if l1:cur.next = l1if l2:cur.next = l2return dummy.next
