Leetcode 143:重排链表(最详细解决方案!!!)

给定一个单链表 LL*0→*L*1→…→*Ln-1→*L*n ,
将其重新排列后变为: L*0→*LnL*1→*Ln-1→L*2→*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

如有问题,希望大家指出!!!

扫描二维码关注公众号,回复: 1621513 查看本文章

猜你喜欢

转载自blog.csdn.net/qq_17550379/article/details/80722615
今日推荐