LeetCode 21. 合并两个有序链表

合并两个有序链表

在这里插入图片描述

链表知识点

  1. 链表是一种物理存储单元上非连续、非顺序的存储结构,是一组数据项的集合,每个数据项都是节点的一部分,每个节点同时包含指向下一节点的链接。
  2. 无论是数组还是链表,都是使用计算机内存(物理内存由一个个大小相同的内存单元构成),然而两者对物理的使用上不一样:链表不一定是连续的内存空间,一般通过next指针来遍历查找。data为自定义的数据,next为下一节点的地址。

链表的基本操作

插入
考虑插入位置的前驱节点与后继节点,其他节点不受影响。

temp = 待插入位置的前驱节点.next
待插入位置的前驱节点.next = 待插入指针
待插入指针.next = temp

删除
将需要删除的节点的前驱指针的next指针修改为其下下个节点

待删除位置的前驱节点.next = 待删除位置的前驱节点.next.next

遍历
链表的遍历是cur = cur.next

当前指针 = 头指针
while 当前节点不为空{
	print(当前节点)
	当前指针 = 当前指针.next
}
for(ListNode cur = head; cur != null; cur = cur.next){
	print(cur.val)
}

解决链表题型

链表的考点:

  • 指针的修改:
    最典型的就是链表反转:递归地反转相邻的两个节点(由于链表的递归性)
#反转一个子链表,并返回新的头与尾
def reverse(self, head: ListNode, tail: ListNode, terminal:ListNode){#head是需要反转的头节点,tail是需要反转的尾节点
	cur = head
	pre = None
	while cur!=terminal:
		#在反转前,记录下一个节点的信息
		next = cur.next
		#修改指针
		cur.next = pre
		#继续往下走
		pre = cur
		cur = next
	#反转后的新的头尾节点返回
	return tail, head
  • 链表的拼接:
    比如本题–合并有序链表

链表需要注意的地方

  • 环:

    1. 判断链表中是否存在环以及环的位置
    2. 对链表操作后出现了环
      如何避免环的出现:通过画图,将所有对指针的操作都反应在图中,能够有效的看出链表中是否构成了环
  • 前后序(进行链表的反转)
    前序遍历:

def dfs(head, pre):
	if not head: 
		return pre
	#留下联系方式(由于后面的都没有处理,因此可以通过head.next定位到下一个)
	next = head.next
	#主逻辑在进入后面节点的前面(由于前面的都已经处理好了,因此不会有环)
	head.next = pre
dfs(head, None)

后续遍历:

def dfs(head):
	if not head or not head.next:
		return head
	#不需要留联系方式,因为后序遍历后面的节点已经走过了
	res = dfs(head.next)
	#主逻辑在进入后面的节点的后面,也就是递归返回的过程会执行到
	head.next.next = head
	#置空。防止环的产生
	head.next = None
	return res

误区

本来想着将两个链表合并,然后sort不就完事了,结果发现没有那么简单。
这里主要考的是递归与链表。

python如何实现链表

新建一个链表

class Node:
	'''
	data:节点保存的数据
	_next:保存下一个节点对象
	'''
	def __init__(self, data, pnext=None):
		self.data = data
		self._next = pnext

链表的常用方法:

LinkedList() #创建空链表
is_empty() #判单链表是否为空
append(data) #在尾部添加一个元素
iter() #遍历链表
insert(idx, value) #插入一个元素,参数为插入元素的索引和值
remove(idx) #移除1个元素
size() #返回链表的元素数
search(item) #查找链表某元素,返回为布尔值

解决

- 递归解法

当一个链表为空,另一个不为空时,可以直接返回不为0的链表,这时可以得到结果。

if not list1: return list2
if not list2: return list1

比较两个链表的指针指向的节点值的大小,递归操作将较小的节点与剩下节点的merge操作结果合并
在这里插入图片描述

if list1.val <= list2.val:
	list1.next = self.mergeTwoLists(list1.next, list2)
	return list1
else:
	list2.next = self.mergeTwoLists(list1, list2.next)
	return list2
  • 迭代解法
    定义一个空链表,用来放置节点:
root = ListNode(-1)
pre = root#当前节点

比较两个链表指针指向的节点值的大小,将较小的节点添加到新链表中

while list1 and list2:
	if list1.val <= list2.val:
		pre.next = list1
		list1 = list1.next
	else:
		pre.next = list2
		list2 = list2.next
	pre = pre.next

两个链表中可能还有未合并元素:

if not list1: pre.next = list2
if not list2: pre.next = list1

参考:
【十分钟知识一览】Python数据结构之链表
合并两个有序链表(python)
LeetCode-21 合并两个有序链表—Python代码实现及详解
力扣加加

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值