博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
leecode142题题解
阅读量:4213 次
发布时间:2019-05-26

本文共 1468 字,大约阅读时间需要 4 分钟。

原题

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

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

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

解题思路

两个关键点:该链路是否为环路,如果是的话,环路起始点在哪里?
1.判断是否有环路。用一个指针遍历结点,如果能走到头即没有回路(注意链路可能为空,所以不光要看fast->next,还要看fast是否为NULL),如果一直往下走即为有回路。
这里就会出现一个问题,有回路就会陷入死循环,解决方法就是使用快慢双指针。fast每次前进两步,
slow每次前进一步,如果能相遇即为有回路,不然慢指针永远追不上快指针(起始点都一样,所以不要用while循环)。快慢指针为何一定相遇,知乎上有用户进行了解答,一下是知乎上的解释:
1:快指针与慢指针之间差一步。此时继续往后走,慢指针前进一步,快指针前进两步,两者相遇。
2:快指针与慢指针之间差两步。此时继续往后走,慢指针前进一步,快指针前进两步,两者之间相差一步,转化为第一种情况。
3:快指针与慢指针之间差N步。此时继续往后走,慢指针前进一步,快指针前进两步,两者之间相差(N+1-2)-> N-1步。因此,此题得证。所以快指针必然与慢指针相遇。又因为快指针速度是慢指针的两倍,所以相遇时必然只绕了一圈。

作者:知乎用户

链接:https://www.zhihu.com/question/23208893/answer/117115415
2.环路起始点在哪里。
将fast和slow的步进都设为1,这样 相遇点必然是链路入口,不然步长一样其他地方不会相遇(当然,此时fast和slow是相遇的,需要将其拉开,将fast重新指向头结点,如果slow此时也在这,那么头结点就是入口)。相遇点一定是回路入口,但是可能有人会担心,快慢指针是不是必然会相遇,有人也对此做了证明:若在头结点和相遇结点分别设一指针,同步(单步)前进,则最后一定相遇在环入口结点p。https://www.cnblogs.com/songdechiu/p/6686520.html

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {
public: ListNode *detectCycle(ListNode *head) {
ListNode *fast,*slow; fast=slow=head; do {
if(fast==NULL ||fast->next ==NULL ) return nullptr ; fast=fast->next ->next ; slow=slow->next ; }while(fast!=slow); fast=head; while(fast!=slow) {
fast=fast->next ; slow=slow->next ; } return fast; }};
你可能感兴趣的文章
线段树 hdoj 1166 敌兵布阵
查看>>
线段树 hdoj 1754
查看>>
线段树习题
查看>>
POJ 1002 487-3279 模拟
查看>>
CodeForces 2018-6-1 div3 D. Points and Powers of Two
查看>>
C/C++ 位运算
查看>>
HDOJ 2045 LELE的RPG难题 递推
查看>>
HOOJ 2047 阿牛的EOF牛肉串 (递推)
查看>>
windows 下远程访问 远程主机ubuntuMysql数据库 遇到的问题
查看>>
STL使用
查看>>
python 用matplotlib 画图
查看>>
常用分类算法在不同样本下的选择
查看>>
python 使用 libsvm
查看>>
android 获取百度地图SDK遇见的问题(只显示网格,也就是调用失败)
查看>>
matplotlib 学习
查看>>
Linux Ubuntu 下改变 Mysql max_connections
查看>>
Android Studio 常用快捷键
查看>>
Android 导入项目遇到的问题
查看>>
Git 学习笔记
查看>>
[CSP]2017-12-3 Crontab
查看>>