LeetCode 刷题记录——21. 合并两个有序链表

这里是昨天的小尾巴。对我来说好吃力啊,我先是学习了一遍链表,再来弄这个题目。太费时间了啊。

递归有点看不太懂

题目:

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

示例:(这题隐含了,需要按大小排序,并且这里是从前往后逐个比的,谁最先小就是谁(交叉)。还有种理解是全部大小排序都可以)

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
比如:交叉
输入:[3,1,2] [2,3,4]
输出:[2,3,3,1,2,4]
比如:排序
输入:[1,4,5] [1,3,3]
输出[1,1,3,3,4,5] 不是[1,1,3,4,3,5]

参考解答:

1.迭代:

思路:因为两个链表都是有序链表(递增),因此可以很容易地找出两个链表中的最小元素,即比较两个链表表头的元素,时间复杂度是 O(1)的。我们可以利用两个指针——指向两个链表的最小节点,每次比较两个指针所指向节点的值,将值比较小的节点加到新的链表中,然后更新指针,如此循环往复直到到达一个链表的尾部。最后,还需要将另一个链表的剩余部分(如果存在的话)添加到新的链表的尾部。思路:选择一条主链表,同时设置2个指针分别指向2个链表。if判断节点值的大小,通过指针的操作使主链表不断增长。

复杂度分析:

  • 时间复杂度:O(m+n),其中,m 为链表 1 的节点数,n为链表 2 的节点数,算法需要遍历两个链表的所有元素
  • 空间复杂度:O(1),只需要保存两个引用
  • 36 ms11.8 MB

先看下繁琐版:(不知道哪里出问题运行不起来)

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        res = ListNode(None)                # todo 1
        dumb_head = res
        while l1 and l2:
            if l1.val<l2.val:
	            print('l1.val,l2.val',l1.val,l2.val)
	            dumb_head.next= l1.next    # todo 2
	            l1 = l1.next
            else:
	            dumb_head.next = l2
	            l2 = l2.next
            node = dumb_head.next
        if l1:
	        dumb_head.next = l1
        else:
	        dumb_head.next = l2             # todo 3
        return res.next
class Solution1(object):
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        if not l1 and not l2:  # l1和l2链表均不存在
            return None
        elif not l1:  # l1链表不存在
            return l2
        else: # l2链表不存在
            return l1
        dumb_head=last_node=ListNode(0)         # todo 1 上面两句合并
	    # last_node = ListNode(None)
        while l1 and l2:
	        if l1.val < l2.val:             #这里是从前往后逐个比的,谁最先小就是谁
		        print('l1.val,l2.val', l1.val, l2.val)
		        last_node.next,l1 = l1,l1.next#todo 2 上面两句合并
	        else:
		        last_node.next,l2 = l2,l2.next
	        last_node = last_node.next
        last_node.next=l1 or l2                  #todo 3这里代替了上面的if else
        return dumb_head.next

if __name__=='__main__':

	l1=ListNode([1,4,2])
	l2=ListNode([1,3,4])
	mm=Solution1().mergeTwoLists(l1,l2)

2.递归

思路:递归的思路和迭代的思路是相同的,都是每次比较两个链表的最小节点,然后对值更小的节点进行操作。不同的是,迭代是从值比较小的节点开始组建新的链表,而递归则是从值比较大的节点开始组建新的链表——递归到其中一个链表的尾部才开始组建新的链表。

复杂度分析:

  • 时间复杂度:O(m+n):,其中,m 为链表 1 的节点数,n为链表 2 的节点数,算法需要遍历两个链表的所有元素
  • 空间复杂度:O(m+n),额外的空间是由于递归调用占用系统栈的空间,递归的深度最多为 m+n层

Python 实现

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

class Solution:
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        if not l1 and not l2:  # l1和l2链表均不存在
            return None
        elif not l1 or not l2:
            return l1 or l2
        
        if l1.val < l2.val:
            l1.next = self.mergeTwoLists(l1.next, l2)
            return l1     #l1小的话,就把l1的下一个节点指向l2节点。
        else:
            l2.next = self.mergeTwoLists(l1, l2.next)
            return l2    #l2小的话,就把12的下一个节点指向l1节点。顺序无关,主要是用谁的.next(类似指针)

3.排序

class Solution3:
	def mergeTwoLists(self, l1, l2):
		"""
		:type l1: ListNode
		:type l2: ListNode
		:rtype: ListNode
		"""
		if not l1 and not l2:
			return
		res = []
		q1, q2 = l1, l2
		while q1:
			res.append(q1)
			q1 = q1.next
			print(q1)  #None
		while q2:
			res.append(q2)
			q2 = q2.next
			print(q2)
		print(res) #[<__main__.ListNode object at 0x7fc8e36d16a0>, <__main__.ListNode object at 0x7fc8e36d16d8>]
		res = sorted(res, key=lambda x: x.val)
		return [i.val for i in res]

总结:

    1.要注意复杂度的问题,学着分析。

    1)递归调用会占用系统栈的空间。递归从后往前看

    2)注意python写法

    2.python用法之sorted:  
    1) 列表排序:sorted(list)
    2) 元组排序:需要用到参数key。用到隐函数lambda,是固定写法,不要写成别的单词;x表示列表中的一个元素,在这里,表示一个元组,x只是临时起的一个名字,你可以使用任意的名字;x[0]表示元组里的第一个元素,意思就是按照列表中第一个元素排序 。当然第二个元素就是x[1]         

	#sorted
	list_a=[('a',1),('c',3,),('b',4)]
	print(sorted(list_a,key=lambda x:x[0]))   #按第一个排序 [('a', 1), ('b', 4), ('c', 3)]
	print(sorted(list_a,key=lambda x:x[1]))   #按第二个排序[('a', 1), ('c', 3), ('b', 4)]
	print(sorted(list_a))                     # 默认是第一个的 [('a', 1), ('b', 4), ('c', 3)]
	print(sorted(list_a,reverse=True))        #倒序 [('c', 3), ('b', 4), ('a', 1)]

3) reverse参数实现倒序排列

3.我依然很菜。
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值