143. 重排链表

143. 重排链表

题意

给定一个单链表 LL0→L1→…→L**n-1→Ln , 将其重新排列后变为: L0→L**nL1→L**n-1→L2→L**n-2→…

并且需要实际的进行节点交换;

解题思路

  • 拆分成两条链表:

    1. 找到中间的结点;

    2. 将链表拆分成左右两条链表,并且将右边的链表进行反转;

    3. 将左右两条链表进行合并;

  • 双端队列:

    1. 将链表结点加入到队列中;

    2. 将从左边取出的结点和右边取出的结点进行连接;

这里需要注意的是虽然说是右边结点在左边结点的前面,但是左边链表的结点是在第一个位置的,比如[1, 2, 3, 4],最后的结果应该是1->4->2->3,这里的1是在第一个的位置,而不是4;

实现

class Solution(object):
   def reorderList(self, head):
       """
      执行用时 : 160 ms, 在Reorder List的Python提交中击败了14.77% 的用户
      内存消耗 : 28.8 MB, 在Reorder List的Python提交中击败了11.11% 的用户
      :type head: ListNode
      :rtype: None Do not return anything, modify head in-place instead.
      """
       if not head or not head.next:
           return

       # 1. 找到中间的结点
       slow, fast = head, head
       while fast.next and fast.next.next:
           slow = slow.next
           fast = fast.next.next

       # 2. 将链表拆分成两部分,并且将右边的链表反转
       rev_head = self.reverse_node(slow.next)
       slow.next = None

       # 3. 将两个链表进行合并
       slow, fast = head, rev_head
       while slow and fast:
           # 分别保存下两条链表的下一个结点的位置
           next_slow = slow.next
           next_fast = fast.next
           # 左边链表的起始结点指向右边链表的起始结点
           slow.next = fast
           # 右边链表的起始结点的指向左边链表的下一个结点
           fast.next = slow.next

           slow = next_slow
           fast = next_fast

   def reverse_node(self, head):
       """
      将链表反转
      :param head:
      :return:
      """
       prev_node, cur_node, next_node = None, head, head.next
       while cur_node:
           next_node = cur_node.next
           cur_node.next = prev_node
           prev_node = cur_node
           cur_node = next_node
       return prev_node

   def reorderList2(self, head):
       """
      执行用时 : 184 ms, 在Reorder List的Python提交中击败了4.55% 的用户
      内存消耗 : 28.8 MB, 在Reorder List的Python提交中击败了11.11% 的用户
      :type head: ListNode
      :rtype: None Do not return anything, modify head in-place instead.
      """
       from collections import deque
       if not head or not head.next:
           return

       tmp = head
       queue = deque()
       while tmp:
           queue.append(tmp)
           tmp = tmp.next

       while queue:
           # 如果不存在说明是起始结点,否则连接左边结点
           if not tmp:
               tmp = queue.popleft()
           else:
               tmp.next = queue.popleft()
               tmp = tmp.next
           if queue:
               # 和右边结点进行连接
               tmp.next = queue.pop()
               tmp = tmp.next

       tmp.next = None
posted @ 2019-03-21 17:19  banananana  阅读(...)  评论(... 编辑 收藏