LeetCode题练习与总结:环形链表--141

202 篇文章 0 订阅
56 篇文章 0 订阅

一、题目描述

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意: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, 10^4]
  • -10^5 <= Node.val <= 10^5
  • pos 为 -1 或者链表中的一个 有效索引 。

二、解题思路

这个问题可以使用快慢指针(Floyd’s cycle-finding algorithm)的算法来解决。我们可以设置两个指针,一个快指针(每次移动两步)和一个慢指针(每次移动一步)。如果链表中存在环,那么快慢指针最终会在环内相遇;如果链表中没有环,快指针将会先到达链表的末尾。

算法步骤:

  1. 初始化快慢两个指针,都指向链表的头节点。
  2. 在快指针没有到达链表末尾的情况下,进行循环: a. 快指针向前移动两步。 b. 慢指针向前移动一步。 c. 检查快慢指针是否相遇。
  3. 如果快慢指针相遇,则链表存在环,返回true。
  4. 如果快指针到达链表末尾,则链表无环,返回false。

三、具体代码

public class Solution {
    public boolean hasCycle(ListNode head) {
        // 快慢指针初始都指向头节点
        ListNode slow = head;
        ListNode fast = head;
        
        // 当快指针没有到达链表末尾时进行循环
        while (fast != null && fast.next != null) {
            slow = slow.next;          // 慢指针前进一步
            fast = fast.next.next;     // 快指针前进两步
            
            // 如果快慢指针相遇,则存在环
            if (slow == fast) {
                return true;
            }
        }
        
        // 如果快指针到达链表末尾,则没有环
        return false;
    }
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 假设链表的长度为 n,如果有环,快指针和慢指针最终会在环内相遇。
  • 在没有遇到慢指针的情况下,快指针每次移动两步,慢指针每次移动一步,因此,每轮循环中,快慢指针之间的距离会减少1。
  • 当快指针进入环时,它需要走 n 步才能追上慢指针(因为慢指针此时已经在环内了)。
  • 因此,最多会有 n 轮循环,每轮循环中快慢指针各移动一次,所以时间复杂度是 O(n)
2. 空间复杂度
  • 快慢指针算法只使用了固定数量的额外空间(两个指针),与链表的长度无关。
  • 因此,空间复杂度是 O(1),即常数空间复杂度。

综上所述,快慢指针算法用于检测链表中的环的时间复杂度是 O(n),空间复杂度是 O(1)

五、总结知识点

  1. 链表(Linked List):链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据和一个或多个指向其他节点的引用(或指针)。

  2. 单链表(Singly Linked List):每个节点只包含一个指向下一个节点的引用的链表。

  3. 节点(Node):链表中的基本单元,通常包含数据和指向下一个节点的指针。

  4. 循环(Loop):在编程中,循环用于重复执行一组指令,直到满足某个条件为止。本代码中使用了一个 while 循环来遍历链表。

  5. 指针(Pointer):在链表的操作中,指针用于跟踪当前处理的节点。本代码中使用了两个指针,一个慢指针和一个快指针。

  6. 快慢指针法(Floyd’s cycle-finding algorithm):这是一种检测链表中是否存在环的方法,通过设置两个速度不同的指针,一个快一个慢,如果在链表中存在环,那么这两个指针最终会在环内相遇。

  7. 条件语句(Conditional Statement):用于根据条件执行不同的代码路径。本代码中使用了 if 语句来检查快慢指针是否相遇。

  8. 空值检查(Null Check):在处理链表时,需要检查节点是否为 null,以避免空指针异常。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一直学习永不止步

谢谢您的鼓励,我会再接再厉的!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值