「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战」。
描述
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true 。 否则,返回 false 。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
提示:
链表中节点的数目范围是 [0, 104]
-105 <= Node.val <= 105
pos 为 -1 或者链表中的一个 有效索引 。
做题
我刚开始做的时候,想着拿第一个节点为基准,一直遍历后面的节点,当节点等于第一个节点时,就说明有环,现在才知道原来这个环不是再从头开始的。
记录节点法
第一种做法:记录节点法,利用哈希表记录遍历过的节点,如果当前的节点存在哈希表中,就说明是有环的。
public boolean hasCycle(ListNode head) {
//记录节点法
Map<ListNode,ListNode> map =new HashMap();
while(head!=null){
ListNode node = map.get(head);
if(node == null){
//当该节点不存在时,存入map
map.put(head,head);
}else{
//当节点存在,说明有环
return true;
}
head=head.next;
}
return false;
}
快慢指针法
第二种做法:快慢指针法,慢指针每次只走一步,快指针走两步,如果有环,那么快慢指针就会相遇。
例如,head = [3,2,0,-4], pos = 1
模拟快慢指针:
快:0 > 2 > -4 > 0 > 2 > -4
慢:2 > 0 > -4 > 2 > 0 > -4
六次就能相遇了,至于为啥会相遇,我也不知道,只能推测,在一个环里,两个指针无论在哪里,一个走两步,另一个走一步,肯定会相遇。
public boolean hasCycle(ListNode head) {
//快慢指针法
ListNode slowIndex=head;
ListNode fastIndex=head;
while( fastIndex!=null && fastIndex.next!=null){
slowIndex = slowIndex.next;
fastIndex = fastIndex.next.next;
if(slowIndex == fastIndex){
return true;
}
}
return false;
}
理论上第二种做法的内存消耗应该会比较小,这里可能是误差的原因。
最后
今天就到这里了。
这里是程序员徐小白,【每日算法】是我新开的一个专栏,在这里主要记录我学习算法的日常,也希望我能够坚持每日学习算法,不知道这样的文章风格您是否喜欢,不要吝啬您免费的赞,您的点赞、收藏以及评论都是我下班后坚持更文的动力。