将其重新排列后变为: L 0→ L n→ L 1→ L n-1→ L 2→ L n-2→…
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:
给定链表 1->2->3->4, 重新排列为 1->4->2->3.
示例 2:
给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.
">
给定一个单链表 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.
寻找链表中点 + 链表逆序 + 合并链表
注意到目标链表即为将原链表的左半端和反转后的右半端合并后的结果。
这样我们的任务即可划分为三步:
-
找到原链表的中点(参考「876. 链表的中间结点」)。
- 我们可以使用快慢指针来 O(N)O(N)O(N) 地找到链表的中间节点。
-
将原链表的右半端反转(参考「206. 反转链表」)。
- 我们可以使用迭代法实现链表的反转。
-
将原链表的两端合并。
- 因为两链表长度相差不超过 111,因此直接合并即可。
Code
class Solution:
def middleNode(self, head: ListNode) -> ListNode:
slow = fast = head
while fast.next and fast.next.next:
slow = slow.next
fast = fast.next.next
return slow
def reverseList(self, head: ListNode) -> ListNode:
prev, curr = None, head
while curr:
nextTemp = curr.next
curr.next = prev
prev = curr
curr = nextTemp
return prev
def mergeList(self, l1: ListNode, l2: ListNode):
while l1 and l2:
l1Tmp = l1.next
l2Tmp = l2.next
l1.next = l2
l1 = l1Tmp
l2.next = l1
l2 = l2Tmp
def reorderList(self, head: ListNode) -> None:
"""
Do not return anything, modify head in-place instead.
"""
if not head:
return
middle = self.middleNode(head)
l1, l2 = head, middle.next
middle.next = None
l2 = self.reverseList(l2)
self.mergeList(l1, l2)
复杂度分析
-
时间复杂度:O(N)O(N)O(N),其中 NNN 是链表中的节点数。
-
空间复杂度:O(1)O(1)O(1)。