原题(Medium): 

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

  为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

  说明:不允许修改给定的链表。

  

思路:

  首先要考虑的就是怎么发现一个链表是否有环,一个比较普遍的解法就是:快慢指针,定义两个指针:一个快指针,快指针每次跨链表的两个节点;一个慢指针,慢指针每次指向下一个节点。如果链表有环,那么两指针迟早会相遇,从而发现有环而结束比遍历,如果没指针,快指针就会到达链表尾部而结束遍历。

  接下来就是难点了,如何找到入环的节点,我们假设入环的节点与链表的首节点距离为a,然后假设入环的节点与快慢指针相遇的那个结点的距离为b,那么在两指针相遇时,我们可以知道快指针走过的距离为a+x圈+b,而慢指针走过的距离为a+y圈+b,且有一个重要的信息就是,在两指针相遇时,快指针走过的距离是慢指针的两倍。就是说a+x+b  = 2(a+y+b) 还有一个条件就是快指针比慢指针多走的路程一定是环长的整数倍(假设是n倍),这是肯定的,因为a的长度两个节点都会走,那么快指针比慢指针多出来的长度就是快的比慢的多走很多圈,即2(a+y+b)  - (a+y+b)  = a+b+y圈 = n 圈:入环节点与链表的首节点距离(a)+入环节点到相遇点之间的距离(b)是环的整数倍(n - y圈),现在我们知道两个指针都在离入环节点距离为b的那个相遇点,而现在a+b是环长度的整数倍,就是说如果慢指针再走a步,就等于慢指针再走了一次a+b的路程,(1圈也好,n圈也好,都是)回到了入环结点的位置,但是问题是,我们不知道a是多少啊?

  我们可以再定义一个指针指向首节点,该指针走a步的同时慢指针也走a步,两者就相遇啦,相遇的节点就是入环节点。

 ListNode *detectCycle(ListNode *head) {
if (head == NULL) return NULL;
ListNode* fast = head;
ListNode* slow = head;
bool hasCycle = false;
//首先,快慢指针判断是否有环
while (fast&& fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
if (fast == slow)
{
hasCycle = true;
break;
}
}
//没环,结束
if (!hasCycle) return NULL;
//有环,两指针同时走,必在a步后相遇,相遇点为入环节点
ListNode* q = head;
while (q != slow)
{
q = q->next;
slow = slow->next;
}
return q;
}

LeetCode | 142. 环形链表 II的更多相关文章

  1. LeetCode 142. 环形链表 II(Linked List Cycle II)

    142. 环形链表 II 142. Linked List Cycle II 题目描述 给定一个链表,返回链表开始入环的第一个节点.如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整 ...

  2. Java实现 LeetCode 142 环形链表 II(二)

    142. 环形链表 II 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始 ...

  3. Leetcode 142.环形链表II

    环形链表II 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 说明:不允许修改给定的链表. 进阶:你是否可以不用额外空间解决此题? 链表头是X,环的第一个节点是Y,sl ...

  4. LeetCode 142——环形链表 II

    1. 题目 2. 解答 2.1 方法 1 定义快慢两个指针,慢指针每次前进一步,快指针每次前进两步,若链表有环,则快慢指针一定会相遇. 当快慢指针相遇时,我们让慢指针指向头节点,快指针不变,然后每次快 ...

  5. LeetCode 142——环形链表II(JAVA)

    给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 - ...

  6. LeetCode 142. 环形链表 II(Linker List Cycle II)

    题目描述 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 说明:不允许修改给定的链表. 进阶: 你是否可以不用额外空间解决此题? 解题思路 分为三步: 首先判断是否存在 ...

  7. leetcode 142. 环形链表 II(c++)

    给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 - ...

  8. 【LeetCode】142. 环形链表 II

    142. 环形链表 II 知识点:链表:set:快慢指针 题目描述 给定一个链表,判断链表中是否有环. 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表 ...

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

    环形链表II 思路 https://www.cnblogs.com/springfor/p/3862125.html https://blog.csdn.net/u010292561/article/ ...

随机推荐

  1. Selenium ChromeDriver与Chrome版本映射表(更新到v77)

    ChromeDriver版本 支持的Chrome版本 v77.0.3865.40 v77 v76.0.3809.126 v76 v75.0.3770.140 v75 v74 v74 v73 v73 v ...

  2. WinDbg常用命令系列---异常相关操作

    .exr (Display Exception Record) .exr命令显示异常记录的内容. .exr Address .exr -1 参数: Address指定异常记录的地址.如果指定-1作为地 ...

  3. C++函数声明后面加throw()的作用

    原文地址:https://blog.csdn.net/to_baidu/article/details/53763683 C++里面为什么有时候在函数声明的时候在后面加throw()关键字? 解释: ...

  4. 1-ESP8266 SDK开发基础入门篇--开发环境搭建

    因为今天终于做好了自己的另一块工控板,所以我就开始写基础公开篇的内容,希望自己小小的努力能够帮到大家 自己做的另一块板子 https://www.cnblogs.com/yangfengwu/cate ...

  5. 18年今日头条笔试第一题题解:球迷(fans)

    其实本题是加强版,原数据是100*100的,老师为了尊重我们的智商加成了3000*3000并进行了字符串处理…… 上原题~ 球迷 [问题描述] 一个球场C的球迷看台可容纳M*N个球迷.官方想统计一共有 ...

  6. PHP 之根据两个经纬度计算距离

    一.函数代码 /** * @param $lng1 * @param $lat1 * @param $lng2 * @param $lat2 * @return float */ function g ...

  7. Vue 自定义编译打包路径

    在 vue.config.js 文件下添加 outputDir 配置项: module.exports = { outputDir:"my_target_direct", // o ...

  8. Windows下多个JDK版本的切换方法

    问题 因我之前在window中无法命令行输入,后来发现是电脑中存在多个JDK,导致设置混乱. 于是,我继续深入研究了当电脑存在多个JDK的情况下,如何设置想要的JDK版本. 步骤 1.更改环境变量 进 ...

  9. vue 中使用阿里iconfont彩色图标

    在main.js中 import './assets/images/iconfont/iconfont.css'import './assets/images/iconfont/iconfont.js ...

  10. vue+elementui搭建后台管理界面(6登录和菜单权限控制[二])

    根据权限计算路由的代码 /** * 通过meta.role判断是否与当前用户权限匹配 * @param roles * @param route */ function hasRoles (roles ...