链表,你有环嘛?

简介: 链表,你有环嘛?

大家好呀,我是蛋蛋。


今天来切环形链表题,依然是面试高频题


判断环形链表在思维上稍微复杂一点儿,但是不慌,有我在。


640.png


   LeetCode 141:环形链表


题意


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


示例


使用整数 pos 表示链表尾连接到链表中的位置(索引从 0 开始)。


输入:head = [3, 2, 0,  -4],pos = 1

输出:true

解释:链表中有一个环,其尾部连接到第 2 个节点。


输入:head = [1],pos = -1

输出:false

解释:链表中没有环。


提示


pos 不作为参数进行传递,仅标识链表的实际情况。

0 <= 链表节点数 <= 10^4

10^-5 <= Node.val <= 10^5

pos 为 -1 或者链表中的一个有效索引。


题目解析


难度简单,解题方法古怪,在实际应用中应该没人脑子瓦特用这种方法。


这种古怪的解题方法就是:快慢指针


快慢指针,顾名思义,是使用速度不同的指针(可用在链表、数组、序列等上面),来解决一些问题。


这些问题主要包括:


  • 处理环上的问题,比如环形链表、环形数组等。
  • 需要知道链表的长度或某个特别位置上的信息的时候。


快慢指针这种算法证明,它们肯定是会相遇的,快的指针一定会追上慢的指针,可以理解成操场上跑步,跑的快的人套圈跑的慢的人


一般用 fast 定义快指针,用 slow 定义慢指针。


速度不同是指 fast 每次多走几步,slow 少走几步。一般设定的都是 fast 走 2 步,slow 走 1 步。


当然设置成别的整数也是可以的,比如 fast 走 3 步,slow 走 1 步。


图解


在本题中使用快慢指针:


  • 若是链表无环,那么 fast 指针会先指向 Null。
  • 若是链表有环,fast 和 slow 迟早会在环中相遇。


以 head = [3, 2, 0, -4],pos = 1 为例。


第 1 步:初始化快慢指针。每次 slow 走 1 步,fast 走 2 步。


640.png

 # 初始化快慢指针
 fast = slow = head

第 2 步:slow 移动 1 步,fast 移动 2 步。

640.png


 while fast and fast.next:
        # 快指针移动 2 步,慢指针移动 1 步
        fast = fast.next.next
        slow = slow.next


第 3 步:同上。

640.png

第 4 步:同上。

640.png


此时 fast = slow,判断有环,返回 true,结束。

# 快慢指针相遇,有环
if fast == slow:
    return True


快慢指针解本题:


  • 链表无环,每个节点至多访问 2 次。
  • 链表有环,最多移动 n 轮。


所以时间复杂度为 O(n)


除此以外,只用了额外的 fast 和 slow 两个指针,所以空间复杂度为 O(1)


代码实现


Python 代码实现

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        # 空链表或链表只有一个节点,无环
        if not head or head.next == None:
            return False
        # 初始化快慢指针
        fast = slow = head
        # 如果不存在环,肯定 fast 先指向 null
        # 细节:fast 每次走 2 步,所以要确定 fast 和 fast.next 不为空,不然会报执行出错。
        while fast and fast.next:
            # 快指针移动 2 步,慢指针移动 1 步
            fast = fast.next.next
            slow = slow.next
            # 快慢指针相遇,有环
            if fast == slow:
                return True
        return False

Java 代码实现

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
/*算法思想:使用快慢指针相遇解决是否存在环的问题*/
public class Solution 
{
    public boolean hasCycle(ListNode head) 
    {
        if(head==null)//头指针为空
            return false;
        ListNode fast=head.next;
        ListNode slow=head;
        while(fast!=null&&fast.next!=null)
        {
            fast=fast.next.next;//快指针
            slow=slow.next;//慢指针
            if(fast==slow)//相遇,则一定存在环,否则慢指针根本跟不上快指针
                return true;
        }
        return false;
    }
}

图解链表是否有环到这就结束辣,是不是也不是很难?


仔细揣摩,注意代码细节,多练多敲就可以立于不败之地,臭宝加油。


别忘了我的点赞在看留言么么哒呀。


我是蛋蛋,我们下次见.

640.gif

相关文章
|
5月前
|
C++
有头链表实现(C++描述)
文章介绍了如何在C++中实现有头链表,包括节点定义、链表类定义以及各种操作如插入、删除和遍历的模板函数实现,并提供了使用整数和自定义数据类型进行操作的示例代码。
23 0
|
10月前
链表之初识
链表之初识
|
10月前
|
存储 缓存 C语言
链表修炼指南
链表修炼指南
|
存储
07 链表
07 链表
38 0
|
存储 C++
链表相关问题的实现
链表相关问题的实现
|
存储 索引
关于链表我所知道的
关于链表我所知道的
109 0
|
存储 算法 Java
【JavaOj】链表十连问
【JavaOj】链表十连问
121 0
|
存储 算法 Java
一文带你深入了解链表(C)
📖作者介绍:22级树莓人(计算机专业),热爱编程<目前在c阶段>——目标C++、Windows,MySQL,Qt,数据结构与算法,Linux,多线程,会持续分享学习成果和小项目的 📖作者主页:热爱编程的小K 📖专栏链接:C 🎉欢迎各位→点赞👏 + 收藏💞 + 留言🔔​ 💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🐾 ———————————————— 版权声明:本文为CSDN博主「热爱编程的小K」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_7215744
|
存储 索引
变幻莫测的链表
双链表 单链表中的指针域只能指向节点的下一个节点。 双链表:每一个节点有两个指针域,一个指向下一个节点,一个指向上一个节点。 双链表 既可以向前查询也可以向后查询。
84 0