《剑指offer》-链表找环入口
题目描述
一个链表中包含环,请找出该链表的环的入口结点。
初步想法是每个节点做几个标记,表示是否被访问过,那么遍历链表的时候就知道哪个被访问到了。但是不会实现。
另一个直觉是判断链表有环的算法中出现过的策略,分别按1x和2x速度遍历,总会相遇。假设环长为n。
容易知道,当1x的指针p1和2x的指针p2相遇时,p1走了x步,p2走了2x步,而p2比p1多走的,有两部分:(1)环内部,p1还没有走过的;(2)换内部,p1和p2重合的
这两部分加起来就是整个环。那么其实p2比p1多走的就是这么一个环的距离,也就是说:
2x-x = n ==> n=x
即:p1当前走了一个环长度的距离。
下图表示了p1和p2相遇在B点的情况,其中A点开始顺时针方向回到A的轨迹就是环形,长度为n。
不妨假设链表总长为L,那么:
CA+A环=CA+n=L ==>L-n=CA
CB=x=n=A环
==> BA弧=L-CB=L-n=CA
也即:BA弧=CA,那么指针p1从B继续走,而指针p2从链表起点C从新开始(但是步长这次取1),则当p2到达A点时,p1也到达A点。
对应到算法中,当1x和2x套圈时,p1和p2按照这个策略继续做while循环,直到再次相遇,就找到了环的入口。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if(pHead==NULL){
return NULL;
}
if(pHead->next==NULL){
return NULL;
}
ListNode* p1=pHead;
ListNode* p2=pHead;
while(p2!=NULL && p2->next!=NULL){
p1=p1->next;
p2=p2->next->next;
if(p1==p2){
p1 = pHead;
while(p1!=p2){
p1=p1->next;
p2=p2->next;
}
if(p1==p2){
return p1;
}
}
}
return NULL;
}
};
《剑指offer》-链表找环入口的更多相关文章
- 剑指Offer——链表中环的入口结点
题目描述: 一个链表中包含环,请找出该链表的环的入口结点. 分析: 设置两个指针p1,p2, 两个指针都从链表的头部开始走,不过p1每次走一步,p2每次走两步. 直到相遇的时候,p2走的长度是p1的两 ...
- python剑指offer 链表中环的入口节点
题目: 一个链表中包含环,请找出该链表的环的入口结点. 思路: 先说个定理:两个指针一个fast.一个slow同时从一个链表的头部出发, fast一次走2步,slow一次走一步,如果该链表有环,两个指 ...
- 剑指offer 链表中环的入口位置
题目描述 一个链表中包含环,请找出该链表的环的入口结点. 思路:这题需要知道a = c,然后head和slow每次走一步,相遇的时候就是第一个入口交点, 注意:for循环或者while循环之后,一 ...
- 【剑指offer】约瑟夫环问题
转载请注明出处:http://blog.csdn.net/ns_code/article/details/27957407 题目描写叙述: 每年六一儿童节,JOBDU都会准备一些小礼物去看望孤儿院的小 ...
- 【Java】 剑指offer(1) 找出数组中重复的数字
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字 ...
- 剑指offer——链表相关问题总结
首先统一链表的数据结构为: struct ListNode { int val; struct ListNode *next; ListNode(int x) :val(x), next(NULL) ...
- 剑指Offer 链表中倒数第k个结点
题目描述 输入一个链表,输出该链表中倒数第k个结点. 思路: 法1:设置2个指针p,q.p先移动k次,然后pq同时后移,p到链表尾尾的时候,q指向倒数第k个节点. 注意://需要考虑k=0,以 ...
- 【剑指offer】找出数组中出现一次的两个数
2013-09-08 10:50:46 一个整型数组中,除了两个数字之外,其他数字都出现了2次,找出这两个只出现一次的数字,要求时间复杂度是O(N),空间复杂度是O(1). 小结: 任何数与0异或,结 ...
- 剑指Offer:找出数组中出现次数超过一半的元素
题目:找出数组中出现次数超过一半的元素 解法:每次删除数组中两个不同的元素,删除后,要查找的那个元素的个数仍然超过删除后的元素总数的一半 #include <stdio.h> int ha ...
随机推荐
- Study 8 —— 数据类型(列表/list)
列表是一个数据的集合,集合内可以放任何数据类型,可对集合进行方便的增删改查操作 1. 定义列表: 方法一: L1 = [] #定义空列表 L2 = ['A', 'B', 'C'] #存3个值,索引0 ...
- Git Bash使用详细教程
https://blog.csdn.net/wangrenbao123/article/details/55511461/
- 转--python 黑魔法2
Python 高效编程小技巧 个人博客:临风|刀背藏身 Python 一直被我拿来写算法题,小程序,因为他使用起来太方便了,各种niubi闪闪的技能点也在写算法的过程中逐渐被挖掘到,感谢万能的谷哥度娘 ...
- 微信现金红包 python
微信现金红包发送接口,好像没法限制一个用户一个活动只能领取一次红包,在调用红包接口上,自己做了限制 REDPACK_RECORD 建表sql -- Create table create table ...
- 关于Mac OS虚拟机下共享文件夹的方法
1.确保左上角苹果标志的旁边是“Finder”: 2.点击"Finder": 3.选择“偏好设置设置”: 4.然后在“通用”标签下勾选“已连接服务器”: OK,搞定! 完成以上 ...
- IEEE 802.1X标准
1.介绍 802.1X是一个IEEE标准,通过对用户进行基于端口的安全认证和对密钥的动态管理,从而实现保护用户用户的位置隐私和身份隐私以及有效保护通信过程中信息安全的目的. 在802.1X协议中,只有 ...
- Python巧用正则表达式,完成接口参数替换
最近给Python11期的小朋友们上课,遇到了一个参数替换的问题,首先描述下场景: 需要参数化的数据如下所示: 这个时候如果利用单纯的if判断和字符串的find和replace方法,做起来是非常不明智 ...
- win10如何获得管理员权限_百度经验
win10如何获得管理员权限_百度经验http://jingyan.baidu.com/article/0aa223755448db88cd0d6450.html 在右下方任务栏的“搜索web和win ...
- Android BroadcastReceiver 面试解析
- ubuntu14.04 boost 1.58.0 安裝
1.首先下载安装包,然后解压, 切换目录 wget -o boost_1_58_0.gar.gz http://sourceforge.net/projects/boost/files/boost/1 ...