打印两个有序链表的公共部分 Python 版

本文介绍了一种高效算法,用于打印两个有序链表的公共部分。通过双指针技术,该算法仅需线性时间即可完成任务。适用于数据结构与算法初学者。

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

题目
给定两个有序链表的头指针head1 和head2,打印两个链表的公共部分

代码
这个函数中我使用了我自己写的单链表类,这个代码在另外一篇blog里。
Python版本的单链表类
该问题的函数如下:

class LinkedListAlgorithms(object):
    def __init__(self):
        pass

    def print_common_part(self, head1, head2):  # 给定两个链表的头指针,打印出公共的部分
        if head1.next == 0 or head2.next == 0:
            print 'No common part between two linked lists.'
        common = []
        while head1 is not None and head2 is not None:
            if head1.value > head2.value:
                head2 = head2.next
            elif head1.value < head2.value:
                head1 = head1.next
            else:
                common.append(head1.value)
                head1, head2 = head1.next, head2.next
                if head1 == 0 or head2 == 0:
                    break
        print 'Common part: ', common

分析
由于是有序链表,所以就不需要一遍遍地去搜索链表中的每个值的大小,如果遇到无序链表,第一件事还是要先排序,毕竟排序的时间复杂度可以做到O(NlogN),而一遍遍的搜索的话,复杂度一定是O(N^2)。
然后使用两个指针,不断地向后推进链表中的位置,直到其中一方搜索完整个链表。

<think>好的,我现在需要回答用户关于如何用Python合并两个有序链表的问题。首先,我得回忆一下相关的数据结构知识,特别是链表的基本操作。有序链表合并是一个经典的问题,通常在算法课程或者面试中会遇到。 用户提供的引用资料里有几个关键点。比如引用3提到用递归的方式,较小的节点连接起来,直到其中一个链表为空。引用5也提到了递归的方法,比较当前节点的值,剩下的部分继续递归处理。另外引用4和5提到了迭代的方法,这应该是另一种常见的解决方案。 首先,我应该明确问题:合并两个升序排列的链表,得到一个新的升序链表。需要保持节点原来的顺序,不能创建新节点,而是调整指针的指向。 接下来,我需要考虑两种主要的实现方式:迭代和递归。这两种方法用户可能都需要了解,所以应该都包括在回答里。根据引用4,迭代法是推荐的,而递归虽然简洁但可能有栈溢出的风险,所以需要说明优缺点。 对于迭代法,通常的做法是创建一个哑节点(dummy node)作为新链表的起始点,这样可以避免处理头节点的特殊情况。然后维护一个当前指针,比较两个链表当前节点的值,将较小的连接到当前指针后面,直到其中一个链表为空。最后将剩余的链表连接到后面。 而递归法的思路是每次比较两个链表的头节点,选择较小的那个作为当前节点,然后递归地处理剩下的部分。递归的终止条件是其中一个链表为空,返回另一个链表即可。 现在需要确保代码的正确性。比如在迭代法中,循环的条件应该是两个链表都不为空。每次比较后,移动对应的链表指针和当前指针。最后处理剩余部分的链表。 对于递归法,需要明确递归函数的作用是返回合并后的链表头,每次递归处理剩下的节点。例如,如果l1的值小,则l1的next指向递归调用处理l1.next和l2的结果。 另外,用户提供的示例代码可能来自不同的引用,需要检查语法是否正确,是否符合Python链表结构。通常链表节点会有val和next属性,所以在代码中需要定义这样的结构。 比如,引用3中的递归方法是否正确?假设链表节点有val和next属性,那么递归调用应该是正确的。例如,如果l1.val <= l2.val,那么l1.next = merge(l1.next, l2),并返回l1。否则处理l2的情况。 同时,用户可能需要了解时间复杂度和空间复杂度。迭代法是O(n+m)时间和O(1)空间(不计输入链表),递归法是O(n+m)时间和O(n+m)栈空间。 另外,需要给出示例输入和输出,比如示例1的两个链表合并后的结果,以帮助用户理解。 现在,我需要组织这些思路,按照用户要求的格式,先介绍问题,再给出方法,分别说明迭代和递归的实现,并提供代码示例。同时,要确保所有的数学表达式使用正确的LaTeX格式,比如时间复杂度写成$O(n+m)$。代码块需要用正确的Python语法,可能用户提供的引用中有代码示例,需要整合并验证是否正确。 最后,生成相关问题,比如关于复杂度分析、优化方法、应用场景等,确保问题与主题相关,并引导进一步学习。 可能需要注意的细节:在Python中,链表节点的定义通常用一个类,比如class ListNode:,然后初始化val和next。但用户的问题可能假设链表已经存在,所以示例代码中可能不需要包含节点的定义,只需处理合并逻辑。 总之,回答需要结构清晰,步骤明确,代码正确,并引用相关的资料。</think>### 如何用 Python 合并两个有序链表? 合并两个有序链表的核心思路是**比较两个链表的头节点值,逐步选择较小值构建新链表**。以下是两种实现方法: --- #### **方法一:迭代法(推荐)** 1. **创建哑节点**作为新链表的起点,简化边界条件处理。 2. **循环比较两个链表的当前节点值**,将较小值接入新链表。 3. **处理剩余节点**,直接将非空链表剩余部分接入末尾。 4. **时间复杂度**:$O(n+m)$,空间复杂度:$O(1)$(不计输入链表)[^4]。 ```python class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def mergeTwoLists(l1: ListNode, l2: ListNode) -> ListNode: dummy = ListNode(-1) current = dummy while l1 and l2: if l1.val <= l2.val: current.next = l1 l1 = l1.next else: current.next = l2 l2 = l2.next current = current.next current.next = l1 if l1 else l2 return dummy.next ``` --- #### **方法二:递归法(简洁但需注意栈溢出风险)** 1. **递归终止条件**:任一链表为空时返回另一链表。 2. **比较头节点值**,将较小节点的 `next` 指向递归结果。 3. **时间复杂度**:$O(n+m)$,空间复杂度:$O(n+m)$(递归栈深度)[^5]。 ```python def mergeTwoLists(l1: ListNode, l2: ListNode) -> ListNode: if not l1: return l2 if not l2: return l1 if l1.val <= l2.val: l1.next = mergeTwoLists(l1.next, l2) return l1 else: l2.next = mergeTwoLists(l1, l2.next) return l2 ``` --- #### **示例说明** - **输入**:链表1为 `1->2->4`,链表2为 `1->3->4` - **输出**:合并后链表为 `1->1->2->3->4->4` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值