【经典算法】Leetcode 141. 环形链表(Java/C/Python3实现含注释说明,Easy)

简介: 【经典算法】Leetcode 141. 环形链表(Java/C/Python3实现含注释说明,Easy)

题目描述

给定一个链表,判断链表中是否有环。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos-1,则在该链表中没有环。

示例 1

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

原题:Leetcode 141. 环形链表

思路及实现

方式一:快慢指针

思路

快慢指针是解决链表环问题的一个常见技巧。在这个方法中,我们设置两个指针,一个快指针(每次移动两步)和一个慢指针(每次移动一步)。如果链表中存在环,那么快指针最终会追上慢指针,即两者会在某个节点相遇;如果链表中没有环,那么快指针会先到达链表尾部(null)。

代码实现

Java版本
public class ListNode {
    int val;
    ListNode next;
    ListNode(int x) {
        val = x;
        next = null;
    }
}
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;
    }
}

说明:

  • 首先检查链表是否为空或只有一个节点,如果是,则肯定没有环。
  • 初始化慢指针 slow 指向头节点,快指针 fast 指向头节点的下一个节点。
  • 进入循环,如果快指针或快指针的下一个节点为空,则链表中没有环。
  • 否则,慢指针每次移动一步,快指针每次移动两步,直到两者相遇或快指针到达链表尾部。
C语言版本
struct ListNode {
    int val;
    struct ListNode *next;
};
bool hasCycle(struct ListNode *head) {
    if (head == NULL || head->next == NULL) {
        return false;
    }
    
    struct ListNode *slow = head;
    struct ListNode *fast = head->next;
    
    while (slow != fast) {
        if (fast == NULL || fast->next == NULL) {
            return false;
        }
        slow = slow->next;
        fast = fast->next->next;
    }
    
    return true;
}

说明:

  • C语言版本的实现与Java版本类似,只是语法和类型定义有所不同。
Python3版本
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        if not head or not head.next:
            return False
        
        slow = head
        fast = head.next
        
        while slow != fast:
            if not fast or not fast.next:
                return False
            slow = slow.next
            fast = fast.next.next
        
        return True

说明:

  • Python版本的实现也遵循同样的逻辑,使用类来定义链表节点,并在Solution类中实现hasCycle方法。

复杂度分析

  • 时间复杂度:O(n),其中n是链表的长度。在链表有环的情况下,快指针每次移动两步,因此最坏情况下需要遍历链表长度的一半;

在链表没有环的情况下,快指针会先到达链表尾部,此时快指针最多遍历整个链表一次。因此,总的时间复杂度是O(n)。

  • 空间复杂度:O(1)。我们使用了常数级别的额外空间来存储两个指针。

方式二:哈希表

思路

使用哈希表(在Python中通常使用字典)来存储已经访问过的节点。遍历链表时,对于每个节点,检查它是否已经在哈希表中。如果节点已经存在,说明链表中存在环;如果节点不存在,则将其添加到哈希表中。

代码实现

Java版本
import java.util.HashSet;
import java.util.Set;
public class Solution {
    public boolean hasCycle(ListNode head) {
        Set<ListNode> visited = new HashSet<>();
        while (head != null) {
            if (visited.contains(head)) {
                return true;
            }
            visited.add(head);
            head = head.next;
        }
        return false;
    }
}

说明:

  • 使用HashSet来存储访问过的节点。
  • 遍历链表,对于每个节点,检查它是否已经在HashSet中。
  • 如果在HashSet中找到了节点,则返回true表示存在环。
  • 如果遍历完整个链表都没有找到重复的节点,则返回false表示没有环。
C语言版本

在C语言中,实现哈希表会稍微复杂一些,通常可以使用数组加哈希函数来模拟哈希表的行为。但考虑到C语言标准库中没有直接支持哈希表的数据结构,这里不展示C语言的哈希表实现,而是使用其他方法(如快慢指针)来解决。

Python3版本
class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        visited = set()
        while head:
            if head in visited:
                return True
            visited.add(head)
            head = head.next
        return False

说明:

  • Python中的字典(dict)可以用来作为哈希表。
  • 遍历链表,使用字典visited来存储访问过的节点。
  • 如果节点已经在visited字典中,说明链表中存在环,返回True
  • 如果遍历完整个链表都没有重复的节点,返回False

复杂度分析

  • 时间复杂度:O(n),其中n是链表的长度。我们最多需要遍历链表一次来检查每个节点。
  • 空间复杂度:O(n)。在最坏的情况下,当链表中存在环时,我们可能需要将链表中的所有节点都添加到哈希表中。因此,空间复杂度与链表的长度成正比。

总结

方式 优点 缺点 时间复杂度 空间复杂度
快慢指针 简洁高效,不需要额外空间(除了指针) 不适用于需要找到环的起始节点或环的长度的情况 O(n) O(1)
哈希表 容易理解和实现,能够检测环的存在 需要额外的空间来存储访问过的节点 O(n) O(n)

相似题目

相似题目 难度 链接
环形链表 II 中等 LeetCode 142
相交链表 中等 LeetCode 160
链表中倒数第k个节点 中等 LeetCode 19
删除链表的倒数第N个节点 中等 LeetCode 143
重新排序链表 中等 LeetCode 143
相关文章
|
4月前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的眼疾识别系统实现~人工智能+卷积网络算法
眼疾识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了4种常见的眼疾图像数据集(白内障、糖尿病性视网膜病变、青光眼和正常眼睛) 再使用通过搭建的算法模型对数据集进行训练得到一个识别精度较高的模型,然后保存为为本地h5格式文件。最后使用Django框架搭建了一个Web网页平台可视化操作界面,实现用户上传一张眼疾图片识别其名称。
324 5
基于Python深度学习的眼疾识别系统实现~人工智能+卷积网络算法
|
1月前
|
存储 监控 算法
员工电脑监控场景下 Python 红黑树算法的深度解析
在当代企业管理范式中,员工电脑监控业已成为一种广泛采用的策略性手段,其核心目标在于维护企业信息安全、提升工作效能并确保合规性。借助对员工电脑操作的实时监测机制,企业能够敏锐洞察潜在风险,诸如数据泄露、恶意软件侵袭等威胁。而员工电脑监控系统的高效运作,高度依赖于底层的数据结构与算法架构。本文旨在深入探究红黑树(Red - Black Tree)这一数据结构在员工电脑监控领域的应用,并通过 Python 代码实例详尽阐释其实现机制。
45 6
|
2月前
|
人工智能 编解码 算法
如何在Python下实现摄像头|屏幕|AI视觉算法数据的RTMP直播推送
本文详细讲解了在Python环境下使用大牛直播SDK实现RTMP推流的过程。从技术背景到代码实现,涵盖Python生态优势、AI视觉算法应用、RTMP稳定性及跨平台支持等内容。通过丰富功能如音频编码、视频编码、实时预览等,结合实际代码示例,为开发者提供完整指南。同时探讨C接口转换Python时的注意事项,包括数据类型映射、内存管理、回调函数等关键点。最终总结Python在RTMP推流与AI视觉算法结合中的重要性与前景,为行业应用带来便利与革新。
122 5
|
3月前
|
存储 Linux iOS开发
Python入门:2.注释与变量的全面解析
在学习Python编程的过程中,注释和变量是必须掌握的两个基础概念。注释帮助我们理解代码的意图,而变量则是用于存储和操作数据的核心工具。熟练掌握这两者,不仅能提高代码的可读性和维护性,还能为后续学习复杂编程概念打下坚实的基础。
Python入门:2.注释与变量的全面解析
|
5月前
|
存储 缓存 监控
局域网屏幕监控系统中的Python数据结构与算法实现
局域网屏幕监控系统用于实时捕获和监控局域网内多台设备的屏幕内容。本文介绍了一种基于Python双端队列(Deque)实现的滑动窗口数据缓存机制,以处理连续的屏幕帧数据流。通过固定长度的窗口,高效增删数据,确保低延迟显示和存储。该算法适用于数据压缩、异常检测等场景,保证系统在高负载下稳定运行。 本文转载自:https://www.vipshare.com
156 66
|
3月前
|
算法 Serverless 数据处理
从集思录可转债数据探秘:Python与C++实现的移动平均算法应用
本文探讨了如何利用移动平均算法分析集思录提供的可转债数据,帮助投资者把握价格趋势。通过Python和C++两种编程语言实现简单移动平均(SMA),展示了数据处理的具体方法。Python代码借助`pandas`库轻松计算5日SMA,而C++代码则通过高效的数据处理展示了SMA的计算过程。集思录平台提供了详尽且及时的可转债数据,助力投资者结合算法与社区讨论,做出更明智的投资决策。掌握这些工具和技术,有助于在复杂多变的金融市场中挖掘更多价值。
92 12
|
3月前
|
算法 安全 网络安全
基于 Python 的布隆过滤器算法在内网行为管理中的应用探究
在复杂多变的网络环境中,内网行为管理至关重要。本文介绍布隆过滤器(Bloom Filter),一种高效的空间节省型概率数据结构,用于判断元素是否存在于集合中。通过多个哈希函数映射到位数组,实现快速访问控制。Python代码示例展示了如何构建和使用布隆过滤器,有效提升企业内网安全性和资源管理效率。
70 9
|
3月前
|
监控 算法 安全
内网桌面监控软件深度解析:基于 Python 实现的 K-Means 算法研究
内网桌面监控软件通过实时监测员工操作,保障企业信息安全并提升效率。本文深入探讨K-Means聚类算法在该软件中的应用,解析其原理与实现。K-Means通过迭代更新簇中心,将数据划分为K个簇类,适用于行为分析、异常检测、资源优化及安全威胁识别等场景。文中提供了Python代码示例,展示如何实现K-Means算法,并模拟内网监控数据进行聚类分析。
82 10
|
4月前
|
存储 算法 安全
控制局域网上网软件之 Python 字典树算法解析
控制局域网上网软件在现代网络管理中至关重要,用于控制设备的上网行为和访问权限。本文聚焦于字典树(Trie Tree)算法的应用,详细阐述其原理、优势及实现。通过字典树,软件能高效进行关键词匹配和过滤,提升系统性能。文中还提供了Python代码示例,展示了字典树在网址过滤和关键词屏蔽中的具体应用,为局域网的安全和管理提供有力支持。
81 17
|
3月前
|
存储 算法 量子技术
解锁文档管理系统高效检索奥秘:Python 哈希表算法探究
在数字化时代,文档管理系统犹如知识宝库,支撑各行各业高效运转。哈希表作为核心数据结构,通过哈希函数将数据映射为固定长度的哈希值,实现快速查找与定位。本文聚焦哈希表在文档管理中的应用,以Python代码示例展示其高效检索特性,并探讨哈希冲突解决策略,助力构建智能化文档管理系统。