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

给定一个单链表 LL0→L1→…→Ln-1→Ln ,
将其重新排列后变为: L0→LnL1→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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值