题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems
特别鸣谢:来自夸夸群的 醉笑陪公看落花@知乎,王不懂不懂@知乎,QFIUNE@csdn
感谢任老师倾囊相授,感谢小伙伴们督促学习,一起进步
141 判断是否有环
给定一个链表,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true 。 否则,返回 false
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/linked-list-cycle
解题思路:
- 从头开始遍历链表,存入hash数组,检查是否有重复
- 快慢指针,如有环,快慢指针必然相遇
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
'''
set() hash 存储唯一的node,如果遇到相同的node,说明有环
'''
# def hasCycle(self, head: ListNode) -> bool:
# nodes = set()
# while(head):
# if head not in nodes:
# nodes.add(head)
# else:
# return True
# head = head.next
# return False
'''
快慢指针
一个指针每次走一步,一个指针每次走两步,有环就会相遇
如果没有环,快指针最快遇到空
'''
def hasCycle(self, head: ListNode) -> bool:
if not head:return False
if not head.next:return False
p = head
q = head.next
while(q.next and q.next.next):
if q == p:
return True
else:
p = p.next
q = q.next.next
return False
142 找环入口
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。
说明:不允许修改给定的链表。
进阶:
你是否可以使用 O(1) 空间解决此题?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/linked-list-cycle-ii
同上,用哈希数组,返回结点即可
class Solution:
'''
space o(n)
'''
def detectCycle(self, head: ListNode) -> ListNode:
nodes = set()
while(head):
if head not in nodes:
nodes.add(head)
else:
return head
head = head.next
return None
142 进阶 找环入口 空间复杂度 O(1),含测试用例
快慢指针,先找到相遇点;快指针一次移动两个,慢指针一次移动一个
再用第三个指针,和慢指针一起移动,保持相同速度,二者在入口点处相遇(证明和测试用例图解见后文笔记)
# Title : lc141_链表找环.py
# Created on: 2021/7/16 16:43
# Definition for singly-linked list.
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def solve(self, head: ListNode) -> ListNode:
if not head:return None
if not head.next:return None
temp = head
p = head
q = head.next
while(p.next and p.next.next):
print(p.val,q.val,temp.val)
if p == q:
while(temp!=p.next):
temp = temp.next
p = p.next
return q.next
p = p.next
q = q.next.next
return None
if __name__ == '__main__':
nodes = [-1,-7,7,-4,19,6,-9,-5,-2,-5]
pos = 5
head = ListNode(nodes[0])
tail = head
for x in nodes[1:]:
newnode = ListNode(x)
tail.next = newnode
tail = newnode
entry = head
for i in range(pos):
entry = entry.next
tail.next = entry
ans = Solution().solve(head)
print(ans.val,nodes[pos])
相关笔记
证明BA=OA
V是速度,P是环长
测试用例图解