Leetcode 刷题 (1) 简单单链表:合并两个有序链表

题目

leetcode 21. 合并两个有序链表

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

在这里插入图片描述

难度:简单

题目分析:重点便是有序二字。有序的链表题在删除重复元素、合并等问题,都难度不大。

同时记得考虑特殊输入,两个均为空链表,一个为空链表的情形。

解法一:递归

给定链表 l1 和 l2, 比较第一个元素,如 l1 第一个元素小于 l2 第一个元素,那返回的列表,表头就是 l1 第一个元素。

少了一个元素的 l1 链表 和 l2 链表,此时又是一个排序问题,于是,我们可以调用我们正在编写(虽然还没完成,但有这个功能啊!),返回的一定是个排好序的链表,接上即可,于是,求解代码如下:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
		if l1 is None:
			return l2
		if l2 is None:
			return l1

		if l1.val <= l2.val:
			l1.next = self.mergeTwoLists(l1.next, l2)
			return l1
		else:
			l2.next = self.mergeTwoLists(l1, l2.next)
			return l2
运行结果:

在这里插入图片描述
搞不明白,一样的代码,就是运行时间不一样……

解法二: 非递归

建立一个新链表,然后依次从两个链表摘元素接上。这种解法的空间会多一个指针,其实不占空间。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
    	head = ListNode(-1)
    	cur = head
    	p1 = l1
    	p2 = l2
    	while p1 and p2:
    		if p1.val <= p2.val:
    			cur.next = p1
    			p1 = p1.next
    		else:
    			cur.next = p2
    			p2 = p2.next
    		cur = cur.next
    	
    	if p1 is None:
    		cur.next = p2
    	else:
    		cur.next = p1
    	return head.next
    	
运行结果:

在这里插入图片描述
可能没充钱……

解法三 非递归,插入

以一个链表为基准,另一个链表依次插入。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
    	if l1 is None:
    		return l2
    	if l2 is None:
    		return l1
    	if l1.val <= l2.val:
    		head = l1
    	else:
    		head = l2
    	p1 = l1
    	p2 = l2
    	while p2 is not None:
    		if p2.val < p1.val
    			while (p2.next is not None) and (p2.next.val < p1.val):
    				p2 = p2.next
    			# 出来之后,就找到 p2.val 大于 p1的
    			l2 = p2.next
    			p2.next = p1
    		else: # 这里是 p1 < p2, 因此找p2的插入位置
    			while (p1.next is not None) and (p1.next.val <= p2.val):
    				p1 = p1.next
    			l2 = p2.next
    			p2.next = p1.next
    			p1.next = p2
    		
    		# 更新,l2的表, 剩下的点
    		p2 = l2
    	return head	
运行结果:

在这里插入图片描述
这个程序有点绕……

题外话

刚查看了Leetcode提交的各种不同运行时间的代码,发现,有些人跟我使用一模一样的代码,时间却只有20ms, 我的程序的一半……这其实说明了,这个网站的时间,仅供参考……不过还好,排名第一的程序,16ms, 用的就是非递归。这至少说明,非递归程序会比非递归程序快。

递归虽然可以快速求解问题,然而却不是解法最快的方法。可以先快速求解问题,不过为了更快解答,还是需要非递归的解法。虽然我的代码,运行结果看不出非递归快,但是,至少提交记录证明了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值