网站首页 > 文章精选 正文
单链表(Singly Linked List)是数据结构中的一种常见形式,其特点是每个节点包含数据和指向下一个节点的指针。在处理单链表的算法题时,有一些常见的技巧和套路可以帮助我们更高效地解决问题。以下是一些常见的技巧和套路:
1.双指针技巧
双指针技巧是解决单链表问题的常用方法,尤其是在处理链表中的环、中点、倒数第k个节点等问题时非常有效。
o 快慢指针(龟兔赛跑算法):
o 应用场景:判断链表是否有环、找到链表的中间节点、找到环的入口点等。
o 实现方式:使用两个指针,一个快指针(每次移动两步)和一个慢指针(每次移动一步)。如果链表有环,快指针最终会追上慢指针。
o 示例代码:
def has_cycle(head):
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False
o 前后指针:
o 应用场景:删除链表的倒数第k个节点、找到链表的倒数第k个节点等。
o 实现方式:使用两个指针,一个先移动k步,然后两个指针同时移动,直到先移动的指针到达链表末尾。
o 示例代码:
def remove_nth_from_end(head, n):
dummy = ListNode(0)
dummy.next = head
first = second = dummy
for _ in range(n + 1):
first = first.next
while first:
first = first.next
second = second.next
second.next = second.next.next
return dummy.next
2.虚拟头节点(Dummy Node)
虚拟头节点技巧可以简化链表操作,尤其是在处理头节点的删除、插入等操作时,避免对头节点的特殊处理。
o 应用场景:删除链表中的节点、合并两个有序链表、反转链表等。
o 实现方式:在链表头部添加一个虚拟节点,使得头节点的操作与其他节点一致。
o 示例代码:
def merge_two_lists(l1, l2):
dummy = ListNode(0)
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
3.反转链表
反转链表是单链表问题中的经典操作,常用于解决回文链表、链表逆序等问题。
o 应用场景:反转整个链表、反转链表的一部分、判断链表是否为回文链表等。
o 实现方式:使用三个指针(prev, current, next)来逐个反转链表中的节点。
o 示例代码:
def reverse_list(head):
prev = None
current = head
while current:
next_node = current.next
current.next = prev
prev = current
current = next_node
return prev
4.链表合并与分割
链表的合并与分割是常见的操作,尤其是在处理多个链表时。
o 应用场景:合并两个有序链表、分割链表(如将链表分为小于某个值和大于某个值的两部分)等。
o 实现方式:使用指针逐个比较和连接节点。
o 示例代码:
def partition(head, x):
before = before_head = ListNode(0)
after = after_head = ListNode(0)
while head:
if head.val < x:
before.next = head
before = before.next
else:
after.next = head
after = after.next
head = head.next
after.next = None
before.next = after_head.next
return before_head.next
5.递归与迭代
递归和迭代是解决链表问题的两种基本方法,各有优缺点。
o 递归:
o 优点:代码简洁,易于理解。
o 缺点:递归深度过大时可能导致栈溢出。
o 应用场景:反转链表、合并链表、判断回文链表等。
o 示例代码:
def reverse_list_recursive(head):
if not head or not head.next:
return head
p = reverse_list_recursive(head.next)
head.next.next = head
head.next = None
return p
o 迭代:
o 优点:效率高,不会出现栈溢出问题。
o 缺点:代码相对复杂。
o 应用场景:反转链表、删除节点、合并链表等。
o 示例代码:
def reverse_list_iterative(head):
prev = None
current = head
while current:
next_node = current.next
current.next = prev
prev = current
current = next_node
return prev
6.链表的环检测与入口点查找
链表的环检测和环入口点查找是常见的面试题,通常使用快慢指针来解决。
o 应用场景:判断链表是否有环、找到环的入口点。
o 实现方式:使用快慢指针找到相遇点,然后通过数学推导找到环的入口点。
o 示例代码:
def detect_cycle(head):
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
break
else:
return None
while head != slow:
head = head.next
slow = slow.next
return head
7.链表的排序
链表的排序通常使用归并排序,因为链表的特性使得归并排序的空间复杂度为O(1)。
o 应用场景:对链表进行排序。
o 实现方式:使用快慢指针找到链表中点,然后递归合并两个有序链表。
o 示例代码:
def sort_list(head):
if not head or not head.next:
return head
slow, fast = head, head.next
while fast and fast.next:
slow = slow.next
fast = fast.next.next
mid = slow.next
slow.next = None
return merge(sort_list(head), sort_list(mid))
def merge(l1, l2):
dummy = ListNode(0)
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
总结
单链表问题的解决通常依赖于双指针、虚拟头节点、递归与迭代等技巧。掌握这些常见的套路可以帮助我们更高效地解决链表相关的问题。在实际应用中,根据具体问题的特点选择合适的技巧和方法是关键。
如果你觉得有用的话,帮忙一键三联。
毕竟:我太想进步了
- 上一篇: 那些经典算法:跳表
- 下一篇: C++:挑战鹅厂面试题(一)--反转链表
猜你喜欢
- 2025-05-15 C语言创建链表
- 2025-05-15 看一遍就理解,图解单链表反转
- 2025-05-15 C++:挑战鹅厂面试题(一)--反转链表
- 2025-05-15 那些经典算法:跳表
- 2025-05-15 数据结构错题收录(十八)
- 2025-05-15 数据结构与算法——带你走进循环链表的相关操作
- 2025-05-15 二叉树展开为链表-迭代法
- 最近发表
-
- 如何提高PyTorch“炼丹”速度?这位小哥总结了17种方法
- 显存告急?微调资源优化的三大法宝
- 大模型训练成本降低近一半!新加坡国立大学最新优化器已投入使用
- Pytorch 入门-day13: 调试与可视化
- 基于昇腾用PyTorch实现CTR模型DIN(Deep interest Netwok)网络
- 神经网络训练全解析:从理论到实战的开发者指南及超参数优化法则
- BattProDeep——深度学习赋能电池老化概率精准预测
- 让AI自己调整超参数,谷歌大脑新优化器火了,自适应多种不同任务
- 神经辐射场(NeRF)实战指南:基于PyTorch的端到端实现
- Pytorch学习-day8: 损失函数与优化器
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)
- mysql数据库面试题 (57)