首页 > 其他分享 >Leetcode 142. 环形链表II(Linked list cycle ii)

Leetcode 142. 环形链表II(Linked list cycle ii)

时间:2023-08-19 12:33:22浏览次数:44  
标签:II slow ListNode fast 链表 142 节点 指针

题目链接

给定一个链表的头节点head, 返回链表开始入环的第一个节点。. 如果链表无环, 则返回 null.

如果链表中有某个节点, 可以通过连续跟踪next指针再次到达, 则链表中存在环. 为了表示给定链表中的环, 评测系统内部使用整数pos来表示链表尾连接到链表中的位置(索引从 0 开始). 如果pos是-1, 则在该链表中没有环.

注意: pos不作为参数进行传递, 仅仅是为了标识链表的实际情况. 不允许修改链表。

示例 1:

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

示例 2:

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

提示:

  • 链表中节点的数目范围在范围 [0, 104] 内
  • -105 <= Node.val <= 105
  • pos 的值为 -1 或者链表中的一个有效索引

思路

这道题首先想到的方法是使用Set去重来判断是否有环以及环的入口在哪个位置.

第二种方法是双指针法(快慢指针), 设置两个指针(slow and fast), slow指针每次前进一个节点, fast指针每次前进两个节点, 只要链表中有环, 它们就一定会相遇.

在这道题中的问题是如何确定环的入口. 可以将链表分为三个部分, 分别是从头节点到环入口的节点数x, 从环入口到fast指针和slow指针相遇的节点数为y, 从相遇节点到环入口的节点数z.

这样相遇时, slow指针走过的节点数为x + y, fast指针走过的节点数为x + y + n(y + z), 这里的n指的是fast指针走了n圈才遇到slow指针, (y + z)表示一个圈内的节点数.

由于fast一次走两个节点, slow一次走一个节点, 所以fast走过的节点数 == slow走过的节点数 * 2

也就是: (x + y) * 2 = x + y + n(y + z), 简化后为x = n(y + z) - y, 最后得到x = (n - 1) * (y + z) + z

由于fast至少走一圈才可以遇到slow指针, 所以n必定大于等于1. 当n == 1时, 公式化简为x = z

也就是从头节点出发一个指针, 从相遇节点出发一个指针, 两指针每次走一个节点, 相遇处即为环形入口节点.

代码实现

HashSet:

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        if(head == null) {
            return null;
        }

        ListNode temp = head;
        Set<ListNode> set = new HashSet<ListNode>();

        while(temp != null) {
            if(set.contains(temp)) {
                return temp;
            } else {
                set.add(temp);
            }
            temp = temp.next;
        }

        return null;
    }
}

快慢指针:

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;

        while(fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;

            if(slow == fast) {
                ListNode tempNode1 = fast;
                ListNode tempNode2 = head;

                while(tempNode1 != tempNode2) {
                    tempNode1 = tempNode1.next;
                    tempNode2 = tempNode2.next;
                }

                return tempNode1;
            }
        }

        return null;
    }
}

标签:II,slow,ListNode,fast,链表,142,节点,指针
From: https://www.cnblogs.com/ahci316/p/17642326.html

相关文章

  • Leetcode 160. 链表相交(Intersection of two linked lists lcci)
    题目链接给定两个单链表的头节点headA和headB,请找出并返回两个单链表相交的起始节点.如果两个链表没有交点,返回null.图示两个链表在节点c1开始相交,题目数据保证整个链式结构中不存在环.示例1:输入:intersectVal=8,listA=[4,1,8,4,5],listB=[5,0,1,8,4,5],sk......
  • 剑指 Offer 36. 二叉搜索树与双向链表
    本题比较重要的有两点:1.一般认为有序的二叉搜索树,都是中序遍历。2.中序遍历的递归顺序,得到的就是排好序的,就是链表的顺序,因此只需管遍历的过程中的链表指向即可。classSolution{public://pre将来指向尾节点,head指向头节点Node*pre=nullptr,*head=nullptr;......
  • 代码随想录算法训练营第三天| 203.移除链表元素 ,707.设计链表 ,206.反转链表
    203.移除链表元素题目给你一个链表的头节点head和一个整数val,请你删除链表中所有满足Node.val==val的节点,并返回新的头节点。第一想法定义一个指针a指向头节点,顺序遍历链表,循环结束的条件是指针a.next为null删除操作是判断a.next.val=val时让a.next=a.next.nex......
  • LCR 026. 重排链表
    LCR026.重排链表/***Definitionforsingly-linkedlist.*publicclassListNode{*intval;*ListNodenext;*ListNode(){}*ListNode(intval){this.val=val;}*ListNode(intval,ListNodenext){this.val=val;this.next......
  • C习题-链表
    1.在一个长度为 n ( n>1 )的单链表上,设有头和尾两个指针,执行()操作与链表的长度有关。A、删除单链表中的第一个元素B、删除单链表中的最后一个元素C、在单链表第一个元素前插入一个新元素D、在单链表最后一个元素后插入一个新元素答案:B;需要遍历至最后一个元素的......
  • The 2022 ICPC Asia Regionals Online Contest (II) EJFB
    The2022ICPCAsiaRegionalsOnlineContest(II)EAnInterestingSequence232323232323323232323232#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;voidsolve(){ lln,k; cin>>n>>k; llres=k; llt=0; for(......
  • #yyds干货盘点# LeetCode程序员面试金典:存在重复元素 II
    题目:给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i]==nums[j] 且 abs(i-j)<=k 。如果存在,返回 true ;否则,返回 false 。 示例 1:输入:nums=[1,2,3,1],k=3输出:true示例2:输入:nums=[1,0,1,1],k=1输出......
  • .net core发布到IIS上出现 HTTP 错误 500.19
    ​1.检查.netcore环境运行环境是否安装完成,类似如下环境​编辑 2.IIS是否安装全本次原因就是IIS未安装全导致的按照网上说的手动重启iis(iisreset)也不行 ​......
  • IIS压缩API返回的JSON数据
    安装IIS压缩功能后点击 配置中选择 system.webServer/httpCompression 点击dynamicTypes 添加以下类型,Json和XML会压缩 ......
  • 链表的创建&遍历打印
    博客地址:https://www.cnblogs.com/zylyehuo/#-*-coding:utf-8-*-classNode:def__init__(self,item):self.item=itemself.next=None#头插法defcreate_linklist_head(li):head=Node(li[0])forelementinli[1:]:......