首页 > 其他分享 >leetcode141.环形链表

leetcode141.环形链表

时间:2024-03-14 15:11:40浏览次数:23  
标签:leetcode141 head 环形 fast next 链表 节点 指针

给你一个链表的头节点 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, 104]
  • -105 <= Node.val <= 105
  • pos 为 -1 或者链表中的一个 有效索引 。

 

进阶:你能用 O(1)(即,常量)内存解决此问题吗?

 

解题方法
法1:哈希表+单指针
以set数据结构作为散列表,存储访问过的节点;

循环遍历链表,记录访问过的节点;

在循环中判断当前节点是否已记录在散列表中,如果有,则为环状链表。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def hasCycle(self, head: Optional[ListNode]) -> bool:
        
        visited = set() # 创建哈希表用以记录遍历经过的节点
        temp = head # 指针指向head

        while temp: # 循环便利链表
            if temp in visited: # 判断是否访问过当前节点
                return True
            visited.add(temp)  # 记录访问过的节点
            temp = temp.next # 移动节点
            
        return None

 

 

法2:双指针(快慢指针)
一快一慢两个指针,慢指针一次走1,快指针一次走2;

以相对速度考虑,如果有环,则一定会相遇;

注意循环条件,判断条件的设计。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def hasCycle(self, head: Optional[ListNode]) -> bool:
        
        # 定义快慢指针,同时从起点head开始
        slow = fast = head

        # 注意判断条件:fast, fast.next都不为None,才能循环
        # fast.next不为 None,也是为了使 fast.next.next 能够被定义
        while fast and fast.next:
            slow = slow.next    # 慢指针,一次走1
            fast = fast.next.next   # 快指针,一次走1
            if slow is fast: # 如果发生相遇,说明存在环
                return True 
        
        return False # 退出循环,说明fast或fast.next有 None, 即无环

 

 

 

标签:leetcode141,head,环形,fast,next,链表,节点,指针
From: https://www.cnblogs.com/chenxiaomeng/p/18072893

相关文章

  • 循环双向链表,精简代码秒懂!(C语言)
    #include<stdio.h>#include<stdlib.h>typedefintE;/***循环双链表*初始化*插入元素*删除元素*求链表总长*@return*/structArrayNode{Ee;structArrayNode*prev;structArrayNode*next;};typedefstructArrayNode*......
  • L2-002 链表去重(25分)
    代码真的好烂啊。一个元素加入之前,修改集合中(va,vb)最后一个元素的下一个地址为当前元素的地址。然后我是把(元素地址,下一个地址)和(元素的值)拆开放到两个集合了,放一个里面有点麻烦不太会处理。#include<bits/stdc++.h>usingnamespacestd;intvis[10010];//是否已经来过ve......
  • 链表中的经典问题——移除链表元素I
    移除链表元素给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val==val 的节点,并返回 新的头节点 。 题解一,迭代法:解题思路:    1.首先需要考虑,链表为空或head节点的值等于val的情况,这里可以引入一个虚拟的哑节点dummy_node,该......
  • leetcode 24.两两交换链表中的节点
    24.两两交换链表中的节点给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。示例1:输入:head=[1,2,3,4]输出:[2,1,4,3]示例2:输入:head=[]输出:[]示例3:输入:head=[1]输出:[1]提......
  • leetcode206. 反转链表
    一、链表(LinkedList)链表,是线性表的链式存储结构。一个链表中有若干个结点,每个结点都包含数据域和地址域两部分。数据域用于存储元素,地址域用于存储前驱或后继的地址。单链表:每个结点只有一个地址域的线性链表;双链表:每个结点都有两个地址域,分别指向前驱结点和后继结点。 ......
  • 【OJ】K 个一组翻转链表
    题目基本思路:用计数+栈实现分段,K个一组地翻转链表。#include<bits/stdc++.h>#include<stack>usingnamespacestd;structlist_node{intval;structlist_node*next;};list_node*input_list(){intval,n;scanf("%d",&n);list_node*phea......
  • 《牛客》-D小红数组操作 (链表)
    思路:采用链表进行动态维护即可我们采用map集合来模拟链表结构(用结构体也是可以的)就是输出需要一点点思考.ACcode:#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongmap<int,int>l,r;intq,x,y,op,k;voidsolve(){ cin>>q; while(q--){ cin>>o......
  • 142. 环形链表 IIc
    /***Definitionforsingly-linkedlist.*structListNode{*intval;*structListNode*next;*};*/structListNode*detectCycle(structListNode*head){structListNode*slow=head,*fast=head;while(fast&&fast->next......
  • JS 链表 - 笔记
    代码:classListNode{/***@constructor*@param{number}val*@param{ListNode}next*/constructor(val,next){this.val=(val===undefined?0:val);this.next=(next===undefined?null:next);......
  • K 个一组翻转链表
    题目:structListNode{intval;ListNode*next;ListNode():val(0),next(nullptr){}ListNode(int_val):val(_val),next(nullptr){}ListNode(int_val,ListNode*_next):val(_val),next(_next){}};classSolution{public:ListNod......