143. 重排链表

143. 重排链表

原始题目链接:https://leetcode-cn.com/problems/reorder-list/
在这里插入图片描述

解题思路:

观察最后重排链表的结果发现,就是将链表的左半部分和翻转后的右半部分进行了合并后的结果。所以根据这个结果,可以先找到原始链表的中间节点,将链表一分为二,然后将右边部分的链表翻转,再合并两个链表,具体来说,合并是交叉合并的顺序,所以最终的解法可以分为3个步骤,具体实现开代码及注释。

  1. 找原始链表的中间节点;
  2. 将右边部分的链表翻转;
  3. 交叉合并两个链表。

代码实现:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:

    # 查找链表中间节点的函数,返回中间节点
    def find_middle_node(self, head: ListNode)-> ListNode:
        # 利用快慢指针来查找
        fast, slow = head, head
        
        while fast.next and fast.next.next:
            fast = fast.next.next
            slow = slow.next
        
        return slow

    # 翻转链表的函数,返回翻转后的链表的头结点
    def reverse_listnode(self, head: ListNode)-> ListNode:
        pre = None
        cur = head
        
        while cur:
            cur_next_node =  cur.next
            cur.next = pre
            pre = cur
            cur = cur_next_node
        
        # pre最后指向了翻转后的链表的头部节点
        return pre

    # 合并两个链表的函数
    def merger_two_listnodes(self, l1: ListNode, l2: ListNode):
        # 根据题意,其实是交叉合并两个链表的节点
        # l1是原始链表的左半部分,l2是翻转后的原始链表的右半部分
        while l1 and l2:
            # 先保存各自链表当前节点的下一个节点,不然修改了当前节点后找不到下一个节点
            l1_next_node = l1.next
            l2_next_noed = l2.next

            # 开始交叉合并
            # 根据题意,l1的下一个节点是翻转后的l2节点
            l1.next = l2
            # l1这个指针指向l1的下一个节点,为了后续操作l1链表
            l1 = l1_next_node

            # 根据题意,l2的下一个节点是l1的下一个节点
            l2.next = l1
            # l2指针指向l2的下一个节点
            l2 = l2_next_noed


    def reorderList(self, head: ListNode) -> None:
        """
        Do not return anything, modify head in-place instead.
        """
        # 先找中间节点,把原始链表分为两部分
        mid_node = self.find_middle_node(head)
        # l1是左边部分,l2是右边部分
        l1 = head
        l2 = mid_node.next
        # 分好后,根据题意,中间节点是最后重排链表的尾节点,所以next域为空
        # 必须在分好后,将mid_node的next域置空
        mid_node.next = None

        # 将右边部分翻转
        l2 = self.reverse_listnode(l2)
        # 合并两个链表
        self.merger_two_listnodes(l1, l2)

参考文献:
https://leetcode-cn.com/problems/reorder-list/solution/zhong-pai-lian-biao-by-leetcode-solution/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值