首页 > 其他分享 >环形链表 (简单易懂)

环形链表 (简单易懂)

时间:2024-12-07 22:58:40浏览次数:12  
标签:head ListNode 复杂度 环形 next 链表 易懂 指针

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

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

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

解题思路:
寻找环:
使用快慢指针法来检测环。
快指针每次移动两步,慢指针每次移动一步。
如果链表中存在环,快指针和慢指针最终会在环内相遇。假设环的长度为 k,链表的非环部分长度为 m,那么在最坏情况下,快指针会在 m + k 步内追上慢指针。
因此,时间复杂度为 O(n),其中 n 是链表的总长度(包括环的部分)。
无环情况:
如果链表中不存在环,快指针会先到达链表末尾(即 p 或 p.next 为 null),此时退出循环。
在这种情况下,时间复杂度也为 O(n),其中 n 是链表的长度。
因此,无论链表中是否存在环,时间复杂度都是 O(n)。

空间复杂度
额外变量:
该方法只使用了两个额外的指针 (p 和 t) 来帮助检测环。
这些变量占用的是常数级别的空间。
因此,空间复杂度为 O(1)。

代码展示:

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */


public class Solution {
    /**
     * 检查给定的单链表中是否存在环。
     *
     * @param head 链表的头节点
     * @return 如果链表中存在环则返回 true,否则返回 false
     */
    public boolean hasCycle(ListNode head) {
        // 初始化两个指针,p 为快指针(每次移动两步),t 为慢指针(每次移动一步)
        ListNode p = head;  // 快指针
        ListNode t = head;  // 慢指针

        // 当快指针 p 及其下一个节点不为空时,继续循环
        while (p != null && p.next != null) {
            // 快指针每次移动两步
            p = p.next.next;
            // 慢指针每次移动一步
            t = t.next;

            // 如果快指针和慢指针相遇,说明链表中存在环
            if (p == t) {
                return true;
            }
        }

        // 如果遍历完整个链表,没有发现环,则返回 false
        return false;
    }
}

标签:head,ListNode,复杂度,环形,next,链表,易懂,指针
From: https://blog.csdn.net/2301_81937222/article/details/144318536

相关文章

  • 数据结构小白一小时手搓环形缓冲区
    什么是环形缓冲区环形缓冲区是一种非常高效且常用的数据结构,特别适用于需要处理数据流的场景。它通过循环利用固定大小的内存空间来实现数据的缓存和传输,避免了频繁的内存分配和释放,提高了系统性能和实时性。理解其工作原理和优缺点,可以帮助开发者更好地选择和使用这种数据......
  • 力扣每日打卡 92.反转链表II
    题目:给你单链表的头指针head和两个整数left和right,其中left<=right。请你反转从位置left到位置right的链表节点,返回反转后的链表。示例:输入:head=[1,2,3,4,5],left=2,right=4输出:[1,4,3,2,5]提示:链表中节点数目为n1<=n<=500-500<=Node.......
  • 实现简单链表
    #include<stdio.h>structstu {   intage;   charname[20];   structstu*next;};intmain(){   structstus1={20,"zhangsan",NULL};   structstus2={21,"lisi",NULL};   structstus3={28,"wang",......
  • 两两交换链表中的节点
    使用递归法,头节点和它后面的节点互换位置,然后指针指向头节点后面的后面的节点,继续调用该函数,直到指针指向空。/**Definitionforsingly-linkedlist.structListNode{intval;ListNode*next;ListNode():val(0),next(nullptr){}ListNode(intx):val(x)......
  • 请使用 js 实现一个双向链表
    classNode{constructor(data){this.data=data;this.prev=null;this.next=null;}}classDoublyLinkedList{constructor(){this.head=null;this.tail=null;this.length=0;}//Addanodetotheendofthe......
  • 力扣61题 -- 旋转链表(C++)
    文章目录一、题目要求二、思路分析三、代码展示一、题目要求给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。示例1:输入:head=[1,2,3,4,5],k=2输出:[4,5,1,2,3]示例2:输入:head=[0,1,2],k=4输出:[2,0,1]二、思路分析以......
  • 随机链表的复制(java),注意NullPointerException
    题目描述:给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 rand......
  • 双向链表的介绍及相关的代码
    双向链表特性逻辑结构:线性结构存储结构:链式结构操作:增删改查代码结构体intlen=0;//定义一个全局变量,来保存长度typedefstructListNade{structListNade*prev;//头指针structListNade*next;//尾指针intdata;......
  • 1204- 链表的中间节点
    链表的中间节点leetcode876题目大意:给定一个链表,找到其中间的节点,如果中间是两个就找到后一个节点解题思路:设定两个链表指针,第一个指向head,第二个指向第一个的下两个节点,这样始终会比第一个快2倍,也就形成了切割,如果说第二个节点的next或者第二个节点为空了就说明走到末尾了,此......
  • 92. 反转链表 II
    链接:92.反转链表II-力扣(LeetCode)方法一:需要分类讨论/*总体思路就是:pleft指向left所在的节点pright指向right所在的节点beforeleft指向left的前一个节点,或者叫做前面没有反转部分的尾节点behindright指向right的后一个节点,或者叫做后面没有反转部分......