首页 > 其他分享 >代码随想录-环形链表II

代码随想录-环形链表II

时间:2024-10-23 11:50:18浏览次数:3  
标签:II head ListNode 随想录 相遇 链表 有环 curNode 指针

题目与解析       

题目链接:环形链表II

本题两个关键点,1、确定有环 2、确定环的入口位置

 提供两种解法,第一种是我借助了一个辅助的列表来记录指针,空间复杂度O(n)比较无脑

  第二种是Carl哥的双指针法,又是套圈问题,虽然很难想,但还是推荐这种方式,这才是算法

解法一:

public class Solution {
    public ListNode detectCycle(ListNode head) {
        //方法一、O(n)的辅助空间。记录的一定不能是val,一定是ListNode,搞个list记录一下它
        List nodeList = new ArrayList<ListNode>();
        ListNode curNode = head;
        while(curNode!=null){
            if(nodeList.contains(curNode)){
                return curNode;
            }
            nodeList.add(curNode);
            curNode = curNode.next;
        }
        return null;
    }
}

解法二:快慢指针

思路

方法二采用快慢两个指针的方式,(1)如果快慢指针相遇,则说明有环 (2)有环确定环的入口,借助数学公式推理。

先来个图标注一下环形链表的x、y、z(引用自网站代码随想录代码随想录)

  1. 假设有环,快指针相对于慢指针每次移动一个距离,所以必然会相遇,可以自己推一下
  2. 那么相遇时快慢指针相遇时走过的路程的比值是 1:2  => 2(x+y) = x+y+n(y+z)  整理得 x=n(y+z)-y = (n-1)(y+z)+z
  3. 当n=1时,说明快指针只走了一圈就与慢指针相遇 => x=z,此时让两个指针分别从head和相遇处出发,两个指针相遇刚好是入口
  4. 当n>1 时,无非是从环里出发的指针在环里多走了几圈,但是相遇位置是一样的,还是入口

代码

public class Solution {
    public ListNode detectCycle(ListNode head) {
        //方法二
        //方法二采用快慢两个指针的方式,(1)如果快慢指针相遇,则说明有环 (2)有环确定环的入口,借助数学公式推理
        //假设有环,快指针相对于慢指针每次移动一个距离,所以必然会相遇,可以自己推一下
        //那么相遇时快慢指针相遇时走过的路程的比值是 1:2  => 2(x+y) = x+y+n(y+z)  整理得 x=n(y+z)-y = (n-1)(y+z)+z
        //当n=1时,说明快指针只走了一圈就与慢指针相遇 => x=z,此时让两个指针分别从head和相遇处出发,两个指针相遇刚好是入口
        //当n>1 时,无非是从环里出发的指针在环里多走了几圈,但是相遇位置是一样的,还是入口处
        ListNode fast = head;
        ListNode slow = head;
        while(fast!=null&&fast.next!=null){
            fast = fast.next.next;
            slow = slow.next;
            //相遇了,说明有环
            if(slow == fast){
                //搞两个指针 1从head出发,2从当前位置出发
                ListNode p1 = head;
                ListNode p2 = slow;
                while(p1!=p2){
                    p1 = p1.next;
                    p2 = p2.next;
                }
                return p1;
            }
        }
        return null;

    }
}

总结

  1. 链表问题两大法宝 ① 虚拟头结点 ②双指针(最多的就是快慢指针)
  2. 链表部分最后两道题都涉及到数学归纳,多少有点难,想不出来就背背吧,再遇到类似的能做出来就行了

标签:II,head,ListNode,随想录,相遇,链表,有环,curNode,指针
From: https://blog.csdn.net/Griezmann_7/article/details/143135399

相关文章

  • 代码随想录-链表相交
    题解与说明要注意区分链表相交是指针相等,而不是值相等。这里当时没有想清楚,还以为leetcode的样例一给错了,原来人家是想强调这个问题哈哈这里给出三种解法:(leetcode格式)①看了代码随想录的解释后,自己写的代码。②看了代码随想录的代码后,对原有的代码循环进行优化。③......
  • 单链表的学习和总结
    单链表的学习和总结1.1 反转链表1.1.1 记录leetcode的题目206.反转链表92.反转链表II25.K个一组翻转链表1.1.2整理总结1.记录链表翻转的几种方法:目前我认为“头插法”更好理解https://leetcode.cn/problems/reverse-linked-list/solutions/2948411/dan-lian-......
  • 代码随想录算法训练营第八天|leetcode344.反转字符串、leetcode541. 反转字符串II、卡
    1leetcode344.反转字符串题目链接:344.反转字符串-力扣(LeetCode)文章链接:代码随想录视频链接:字符串基础操作!|LeetCode:344.反转字符串_哔哩哔哩_bilibili自己的思路:直接使用python的内置函数reverse进行一个操作1.1自己的代码1.1.1python的内置函数classSolution:......
  • 3185. 构成整天的下标对数目 II
    给你一个整数数组hours,表示以小时为单位的时间,返回一个整数,表示满足i<j且hours[i]+hours[j]构成整天的下标对i,j的数目。整天定义为时间持续时间是24小时的整数倍。例如,1天是24小时,2天是48小时,3天是72小时,以此类推。示例1:输入:hours=[12,12,......
  • 刚刚学了链表感觉好难(||^||)
    理念听得差不多明白了,但实现起来感觉好难,老师在上面写代码的时候一蹴而就,我自己尝试的时候一窍不通,下课花了好久才写出差不多的代码,大家有什么好方法吗?球球了(>_<)附上了写的链表代码,也欢迎大家提改进建议#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdli......
  • Java毕设项目案例实战II 基于移动平台的远程在线诊疗系统(开发文档+数据库+源码)
    目录一、前言二、技术介绍三、系统实现四、论文参考五、核心代码六、源码获取全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末一、前言在当今数字化时代,医疗行业正经历着前所未......
  • 代码随想录算法训练营day22和day23 | 77. 组合 216.组合总和III 17.电话号码的字母
    学习资料:https://programmercarl.com/回溯算法理论基础.html回溯法backtracking:for循环控制递归数量,暴力搜索:组合、切割、子集、排列、棋盘今天学了组合和切割可以画个N叉树的图来帮助理解回溯过程组合又包括1.单个数组(要加startIndex参数)或多个数组;2.数组内有无重复元素;3.数......
  • 【快慢指针】LeetCode 143. 重排链表
    题解用快慢指针先找到中间结点,然后断开前后两条链,用头插法的思路逆转后面那条链,最后两条链依次从前往后遍历插入即可。参考代码/***Definitionforsingly-linkedlist.*structListNode{*intval;*ListNode*next;*ListNode():val(0),next(nul......
  • 代码随想录算法训练营 | 图论理论基础,98. 所有可达路径
    图论理论基础1.图的种类:有向图,无向图,加权有向图,加权无向图;2.度:无向图中有几条边连接该节点,该节点就有几度,在有向图中,每个节点有出度和入度;出度:从该节点出发的边的个数;入度:指向该节点边的个数;3.连通图:在无向图中,任何两个节点都是可以到达的;强连通图:在有向图中,任何两个节点是可以......
  • 数据结构 链表 C语言
    数据结构第二章的链表//线性表的链式存储#include<stdlib.h>#include<stdio.h>typedefintElemType;typedefstructnode{ElemTypedata;structnode*next;}Node,*LinkList;//初始化空的单链表voidInitList(LinkList*L){*L=(LinkLis......