给定一个单链表 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) 地找到链表的中间节点。
将原链表的右半端反转(参考「206. 反转链表」)。
我们可以使用迭代法实现链表的反转。
将原链表的两端合并。
因为两链表长度相差不超过 1,因此直接合并即可。
Python代码:
# 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:
return None
mid = self.middleNode(head)
h1 = head
h2 = mid.next
mid.next = None
h2 = self.reverseList(h2)
self.mergeList(h1, h2)
def middleNode(self, head):
fast = slow = head
while fast.next and fast.next.next:
fast = fast.next.next
slow = slow.next
return slow
def reverseList(self, head):
cur = head
pre = None
while cur:
nex = cur.next
cur.next = pre
pre = cur
cur = nex
return pre
def mergeList(self, h1, h2):
while h1 and h2:
nex1 = h1.next
nex2 = h2.next
h1.next = h2
h1 = nex1
h2.next = h1
h2 = nex2