返回
快慢指针打造两条线,环形链表抓住尾:LeetCode经典挑战之环形链表II
前端
2023-10-05 22:47:18
前言:环形链表简介
环形链表是一种特殊的数据结构,它的特点是最后一个节点指向第一个节点,从而形成一个环。这种数据结构在实际开发中经常用到,比如音乐播放器中的歌曲列表、浏览器中的历史记录等。
快慢指针思想探秘
理解环形链表,少不了要认识一个关键的思想——快慢指针。快慢指针是一种经典的算法思想,它利用两个指针同时遍历链表,一个指针的速度较快,另一个指针的速度较慢。当快指针追上慢指针时,说明链表中存在环。
举个例子:
假设我们有一个环形链表,包含5个节点。快指针和慢指针从头节点同时出发,快指针每次移动两步,而慢指针每次移动一步。
初始状态:
快指针指向头节点A
慢指针指向头节点A
第一次移动:
快指针指向C
慢指针指向B
第二次移动:
快指针指向E
慢指针指向C
第三次移动:
快指针追上了慢指针
此时,我们可以确定链表中存在环。
代码实现:
def has_cycle(head):
"""
判断链表中是否存在环。
Args:
head: 链表的头节点。
Returns:
True if there is a cycle in the linked list, False otherwise.
"""
# 设置快慢指针
slow = head
fast = head
# 循环遍历链表,直到快指针追上慢指针或到达链表末尾
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
# 如果快指针到达链表末尾,说明链表中不存在环
return False
LeetCode 142:环形链表II
LeetCode 142 环形链表II 是一个经典的题目,它要求我们在不修改链表的情况下,找到环形链表的入口节点。
算法思路:
- 使用快慢指针找到环形链表中的相遇点。
- 设置一个新的指针,从头节点出发,与相遇点同时向后移动。
- 当两个指针相遇时,就是环形链表的入口节点。
代码实现:
def detect_cycle(head):
"""
找到环形链表的入口节点。
Args:
head: 链表的头节点。
Returns:
The entrance node of the cycle, or None if there is no cycle.
"""
# 使用快慢指针找到环形链表中的相遇点
slow = head
fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
break
# 如果链表中不存在环,直接返回None
if not fast or not fast.next:
return None
# 设置一个新的指针,从头节点出发,与相遇点同时向后移动
ptr1 = head
ptr2 = slow
# 当两个指针相遇时,就是环形链表的入口节点
while ptr1 != ptr2:
ptr1 = ptr1.next
ptr2 = ptr2.next
# 返回环形链表的入口节点
return ptr1
结语
环形链表是数据结构中一个重要的知识点,它在实际开发中经常用到。理解环形链表的结构和算法,对于算法工程师来说非常重要。快慢指针的思想,也是算法学习中经常遇到的思想,掌握这个思想,可以帮助你解决很多复杂的问题。