给定一个单链表 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.
解题思路
我首先想到的思路是通过两个stack
将中间元素的左边和右边分别入栈。
stack1: 1 2
stack2: 4 5
mid: 3
然后先弹出stack1
,在弹出stack2
,最后弹出mid
即可。现在的问题变成,我们怎么获得mid
?我们可以通过两个指针,这两个指针,一个快lat=lat.next.next
,一个慢pre=pre.next.next
pre lat
1 -> 2 -> 3 -> 4 -> 5 -> null
但是这种做法没有符合题意,题目要求是在原有的链表上操作。怎么办呢?其实我们得到中间节点后问题已经快要解决了。我们可以将后面的链表reverse
,然后每个一个元素去除前面的链表节点和后面的链表节点,如下:
1 -> 2 -> null
5 -> 4 -> 3 -> null
代码如下:
class Solution:
def reorderList(self, head):
"""
:type head: ListNode
:rtype: void Do not return anything, modify head in-place instead.
"""
if head == None or head.next == None:
return
pre = head
lat = head.next
while lat != None and lat.next != None:
pre = pre.next
lat = lat.next.next
p = pre.next
pre.next = None
# reverse
cur = None
while p != None:
q = p.next
p.next = cur
cur = p
p = q
pre = head
while pre != None and cur != None:
tmp = cur.next
cur.next = pre.next
pre.next = cur
pre = pre.next.next
cur = tmp
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!