每日算法题 14---14.环形链表

题目

14.环形链表

要求

给你一个链表的头节点 head ,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。

注意:pos 不作为参数进行传递。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false

示例

思路1(快慢指针)

我们定义两个指针,一快一满,慢指针每次只移动一步,而快指针每次移动两步,如果该链表快慢指针永远不相遇,那么说明这个链表中不存在环,如果某个时刻快慢指针相遇,那说明该链表存在环。相遇的原理就类似于两个人在环形操场上跑步,一快一慢,不管怎么样一直跑下去总会有相遇的一刻;但如果在直行路上走路,一快一慢注定不会相遇(前提是慢起点在快起点后面)

时间复杂度为O(N)、空间复杂度为O(1) (只用到了两个指针的空间)

我们根据这个原理来实现环的确认

代码1

java 复制代码
public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head==null || head.next==null){
            return false;
        }
        ListNode slow=head;
        ListNode fast=head.next;
        while(slow!=fast){
            if(fast==null||fast.next==null){
                return false;
            }
            slow=slow.next;
            fast=fast.next.next;
        }
        return true;
    }
}

思路2(哈希表)

我们可以利用哈希表的性质来查看环是否存在,每次遍历一个节点时,如果该节点已经存在哈希表里,则说明这个链表中有环,反之将该节点加入哈希表,重复这个过程,知道我们遍历完整个链表

注意我们这次用HashSet,HashSet和HashMap的区别在于前者专门用于存储唯一元素的集合,不需要存键值对,后者是可以用来存储元素出现次数,需要存键值对,在这道题中我们只需要判断该节点是否存在过,因此用前者比较合适

时间复杂度为O(N)、空间复杂度为O(N)(主要为哈希表的开销)

代码2

java 复制代码
public class Solution {
    public boolean hasCycle(ListNode head) {
        Set<ListNode> seen = new HashSet<ListNode>();
        while (head != null) {
            if (!seen.add(head)) {
                return true;
            }
            head = head.next;
        }
        return false;
    }
}

小舟有话说

这道题也可以用来练习链表,加深对链表的认识

如果觉得这两个思路有帮助到你,可以点个关注哦~

相关推荐
2401_833197732 小时前
C++代码切片分析
开发语言·c++·算法
m0_621438522 小时前
实时音频处理C++实现
开发语言·c++·算法
weixin_421922692 小时前
模板代码性能测试
开发语言·c++·算法
Liu628882 小时前
C++中的模板方法模式
开发语言·c++·算法
qq_334903152 小时前
高性能网络协议栈
开发语言·c++·算法
光电笑映2 小时前
STL 源码解剖系列:map/set 的底层复用与红黑树封装
c语言·数据结构·c++·算法
阿贵---2 小时前
模板编译期循环展开
开发语言·c++·算法
2601_954023662 小时前
Beyond the Hype: Deconstructing the 2025 High-Performance Stack for Agencies
java·开发语言·算法·seo·wordpress·gpl
沉鱼.442 小时前
滑动窗口问题
数据结构·算法