每日算法题 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;
    }
}

小舟有话说

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

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

相关推荐
fpcc26 分钟前
数据结构—表
数据结构
YuK.W1 小时前
Leetcode100: 70.爬楼梯、118.杨辉三角、198.打家劫舍
java·算法·leetcode
随意起个昵称1 小时前
状压dp-基础题目2([USACO12MAR] Cows in a Skyscraper G)
c++·算法·动态规划
Funing71 小时前
FreeRTOS学习day1:Keil 工程配置与 FreeRTOS 链表机制理解
数据结构·学习·链表
Jerry2 小时前
LeetCode 1002. 查找共用字符
算法
无限的鲜花2 小时前
协程本质是函数加状态机——零基础深入浅出 C++20 协程
c++·算法·c++20
旖-旎3 小时前
《LeetCode 64 最小路径和 || LeetCode 174 地下城游戏》
c++·算法·leetcode·动态规划
森林古猿13 小时前
再论斜率优化
c++·学习·算法
万法若空3 小时前
【数学-简单数论】同余中的逆
线性代数·算法
凯瑟琳.奥古斯特4 小时前
力扣1009补码解法C++实现
开发语言·c++·算法·leetcode·职场和发展