【LeetCode】剑指 Offer II 026. 重排链表

这篇博客介绍了如何解决一道常见的链表问题,涉及链表的拆分、翻转和交叉合并操作。作者通过两次面试经历阐述了这个问题,并提供了两种不同的解决方案。在合并链表时,特别注意了尾节点的处理。代码实现中包括了详细的步骤和注释,帮助理解每个部分的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 会做不代表熟练
  • 这道题我遇到过好几次。
    (1)第一次是B站的语音算法工程师岗(2023年5月校招面试一面),写出来了;
    (2)第二次是360的自然语言处理工程师岗(2023年6月2日校招一面,没写出来)
    其实第一次写出来的时候是比较卡的,因为我好久没有笔试了,但是思路可能比较顺畅,知道怎么处理细节;写完也就没管了,哪知道后面又遇到了这题,所以还是得熟练。

1.题目

题目还行,但是需要注意的地方有很多,首先需要思路清楚。在思路清楚的基础上再注意细节。

2.分析

分成几个部分来做,分别是:

  • step1.先split 链表
  • step2.再翻转链表,
  • step3.再交叉合并链表。
    在第三步中,需要注意尾节点的一个处理。如下图所示:
    在这里插入图片描述
    当我们已经合并得到1->4 时,后面的2 与 3,需要尾节点串联起来,那么这个串联部分的代码怎么写?主要是想清楚才好写!

3.代码

本文提供两个版本的代码:
代码一:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reorderList(self, head: ListNode) -> None:
        """
        Do not return anything, modify head in-place instead.
        """
        # step1.先split 链表
        # step2. 翻转链表
        # step3. merge 链表
        head1,head2 = self.splitLink(head)
        head2 = self.reverseLink(head2)
        start = self.mergeLink(head1,head2)
        return start

    def splitLink(self,head):
        slow = fast = head
        while(fast.next and fast.next.next):
            slow = slow.next
            fast = fast.next.next
        tmp = slow.next 
        slow.next = None
        # 返回两个链表的头节点        
        return head,tmp

    # 翻转链表
    def reverseLink(self,head):
        pre = None
        while(head):
            nx = head.next
            head.next = pre
            pre = head
            head = nx
        return pre

    # 交叉匹配即可
    def mergeLink(self,head1,head2):        
        cur,head = head1 ,head1
        head1 = head1.next # 往后
        cur.next = None # 初始化
        cnt = 0        
        while(head1 and head2):            
            if cnt% 2 == 0: # 接head2                
                cur.next = head2
                head2 = head2.next
                cur = cur.next
                cur.next = None
            else: # 接head1                
                cur.next = head1
                head1 = head1.next
                cur = cur.next
                cur.next = None
            cnt += 1
        
        if head1:
            cur.next = head1
        if head2:
            cur.next = head2
        return head

代码一应该是没有代码二好懂的,代码二如下:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reorderList(self, head: ListNode) -> None:
        """
        Do not return anything, modify head in-place instead.
        """
        if head is None or head.next is None:
            return head
        # step1. 得到链表的中点 
        slow = fast = head
        while(fast and fast.next and fast.next.next):
            fast = fast.next.next
            slow = slow.next
        # 得到第二个链表的头结点
        h2 = slow.next
        slow.next = None # 置为空

        # step2. 将链表翻转
        pre = None
        while(h2):
            tmp = h2.next
            h2.next = pre
            pre = h2
            h2 = tmp

        # 得到第二个链表的头
        h2 = pre
        # print(h2.val)
        # while(h2):
        #     print(h2.val)
        #     h2 = h2.next
        
        # step3. 拼接两个链表
        h1 = res = head # 最后返回的结果
        tail = None # 表示合并得到链表的尾节点
        while(h1 and h2):
            tmp1 = h1.next
            tmp2 = h2.next
            h1.next = h2
            if cur is None:
                tail = h2
            else:
                tail.next = h1
                tail = h2 # 更新尾节点                            
            # 更新节点
            h1 = tmp1
            h2 = tmp2

        if h1:
            tail.next = h1
        return res
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

说文科技

看书人不妨赏个酒钱?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值