21.合并两个有序链表——python版(做题解析)

题目:
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        if l1 is None:
            return l2
        elif l2 is None:
            return l1
        elif l1.val < l2.val:
            l1.next = self.mergeTwoLists(l1.next, l2)
            return l1
        elif l2.val <= l1.val:
            l2.next = self.mergeTwoLists(l2.next, l1)
            return l2

解题思路:这里使用到的是递归的思路。我们最需要在链表中解决的问题就是,谁连接在谁的后面。如果的l1.val < l2.val那么就将l1.next(这个车厢的链接处)与后面那个车厢相连。反之亦然。

重点解析
1.elif:这是else if的缩写,常用在if语句中
2.链表中常包含两个值,l1.val代表的是第一个车厢的值,l1.next代表的是车厢的连接方式
3.l1.next = self.mergeTwoLists(l1.next,l2)我们在调用函数的时候,要先给上函数的名字,在递归方法中多用self.xxx这样表示自己调用自己
处理结果
在这里插入图片描述
递归法对于新手来说确实不太好理解,务必要先搞清楚链表的结构再来看这道题目。
来源:力扣(LeetCode)

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 实现一个合并两个有序链表的函数,可以按照以下步骤进行: 1. 定义一个链表,作为合并后的结果。 2. 比较两个链表的头节点,将较小的节点加入链表中,并将该链表的头节点指向下一个节点。 3. 重复步骤2,直到其中一个链表为空。 4. 将另一个链表的剩余节点加入链表中。 5. 返回链表作为合并后的结果。 具体实现可以参考以下代码: ``` struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) { struct ListNode* result = NULL; struct ListNode** tail = &result; while (l1 && l2) { if (l1->val < l2->val) { *tail = l1; l1 = l1->next; } else { *tail = l2; l2 = l2->next; } tail = &((*tail)->next); } *tail = l1 ? l1 : l2; return result; } ``` ### 回答2: 合并两个有序链表一个常见的问题,并且可以通过很多种算法来解决。在这里,我们将使用其中最简单的一种方法,也是最容易理解的方法。这个算法的思路非常简单:我们只需要从两个链表中每次选取一个元素,比较它们的大小,将较小的元素添加到链表中,并将相应的指针后移。重复这个过程,直到其中一个链表的元素全部被处理完。最后,将剩余的元素添加到链表的末尾,即可得到已合并有序链表。 具体实现时,我们可以使用三个指针p1、p2和p3。首先,将p1和p2分别初始化为两个有序链表的头节点,将p3指向链表的头节点(这个节点可以在最开始就创建好,并初始化为NULL)。接下来,比较p1和p2的值,如果p1的值小于等于p2的值,就将p1所指向的节点添加到链表中,并将p1指针后移;否则,将p2所指向的节点添加到链表中,并将p2指针后移。重复这个过程,直到p1或p2中有一个指针指向了NULL节点。最后,将剩余的节点添加到链表的末尾,并返回链表的头节点。 这个算法的时间复杂度是O(m+n),其中m和n分别是两个有序链表的长度。空间复杂度是O(1),因为我们只需要使用三个指针来遍历和构建链表。这个算法非常简单,易于理解和实现,适合于处理小型有序链表。如果需要处理大型链表或需要更高效的算法,可以考虑其他更复杂的方法,例如归并排序。 ### 回答3: 合并两个有序链表是一道经典的数据结构问题,涉及到链表的遍历、比较和节点链接操作。对于这个问题,可以通过递归或迭代两种方法实现。 递归方法:定义一个链表,将两个有序链表头节点逐个比较,找出较小的节点作为链表的下一个节点,然后递归调用该方法处理剩余的节点,最终返回链表的头节点即可。 迭代方法:同样定义一个链表,然后使用一个指针依次遍历两个有序链表,每次将较小的节点插入到链表的末尾,并将指针向后移动。当其中一个链表遍历结束后,直接将剩余的节点接到链表的末尾即可。 无论是递归还是迭代方法,都要注意处理一些边界情况,例如某个链表为空,或者两个链表长度不一致等情况。 下面是一个使用迭代方法实现的示例代码: ``` class ListNode { public: int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class Solution { public: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { ListNode* dummy = new ListNode(0); ListNode* cur = dummy; while (l1 != NULL && l2 != NULL) { if (l1->val < l2->val) { cur->next = l1; l1 = l1->next; } else { cur->next = l2; l2 = l2->next; } cur = cur->next; } if (l1 != NULL) { cur->next = l1; } if (l2 != NULL) { cur->next = l2; } return dummy->next; } }; ``` 以上代码创建了一个虚拟头节点 `dummy`,然后通过 `cur` 指针依次遍历两个链表,将较小的值插入到链表的末尾。最后再将未遍历完的链表接到链表的末尾,返回头节点即可。 总而言之,合并两个有序链表是算法面试中经常涉及到的问题,需要掌握递归和迭代两种方法,以及链表的基本操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值