You are given the head of a singly linked-list. The list can be represented as:
L0 → L1 → … → Ln - 1 → Ln
Reorder the list to be on the following form:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
You may not modify the values in the list's nodes. Only nodes themselves may be changed.
Input: head = [1,2,3,4] Output: [1,4,2,3]
Input: head = [1,2,3,4,5] Output: [1,5,2,4,3]
class Solution(object):
def reorderList(self, head):
"""
:type head: ListNode
:rtype: None Do not return anything, modify head in-place instead.
"""
if not head:
return None
p,slow,fast=head,head,head #p保留head节点,用于最后的return
while fast and fast.next:
slow,fast=slow.next,fast.next.next
pre,cur,slow.next=None,slow.next,None #准备两个指针pre和cur用于反转后半部分,并断开slow和后半部分的连接。
while cur:
cur.next,pre,cur=pre,cur,cur.next
#并列赋值时,每一个参数都是进入语句之前的参数,右边的赋值并不会受左边改动的影响。这里反转链表:cur指向pre,pre移动到cur,cur移动到进入语句之前的cur.next的位置。
while head and pre:
head.next,head,pre.next,pre=pre,head.next,head.next,pre.next
#同理,拼接两个链表:a1-b1-a2-b2...,要a1后接b1,然后a1指针移动到原来链表a2; b1后接a2,然后b1指针移动到原来链表的b2。因此,要后面语句不受前面改动的影响,用并列赋值。第三项赋值pre.next=head.next就很明显,尽管前面head向后移动了一个节点,但由于还没走出并列语句,所以head还是a1,head.next才是a2。只有并列赋值语句整体运行完后,head,pre才改变位置。
return p