题目描述

一个链表中包含环,请找出该链表的环的入口结点。

初步想法是每个节点做几个标记,表示是否被访问过,那么遍历链表的时候就知道哪个被访问到了。但是不会实现。

另一个直觉是判断链表有环的算法中出现过的策略,分别按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》-链表找环入口的更多相关文章

  1. 剑指Offer——链表中环的入口结点

    题目描述: 一个链表中包含环,请找出该链表的环的入口结点. 分析: 设置两个指针p1,p2, 两个指针都从链表的头部开始走,不过p1每次走一步,p2每次走两步. 直到相遇的时候,p2走的长度是p1的两 ...

  2. python剑指offer 链表中环的入口节点

    题目: 一个链表中包含环,请找出该链表的环的入口结点. 思路: 先说个定理:两个指针一个fast.一个slow同时从一个链表的头部出发, fast一次走2步,slow一次走一步,如果该链表有环,两个指 ...

  3. 剑指offer 链表中环的入口位置

    题目描述 一个链表中包含环,请找出该链表的环的入口结点.   思路:这题需要知道a = c,然后head和slow每次走一步,相遇的时候就是第一个入口交点, 注意:for循环或者while循环之后,一 ...

  4. 【剑指offer】约瑟夫环问题

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/27957407 题目描写叙述: 每年六一儿童节,JOBDU都会准备一些小礼物去看望孤儿院的小 ...

  5. 【Java】 剑指offer(1) 找出数组中重复的数字

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字 ...

  6. 剑指offer——链表相关问题总结

    首先统一链表的数据结构为: struct ListNode { int val; struct ListNode *next; ListNode(int x) :val(x), next(NULL) ...

  7. 剑指Offer 链表中倒数第k个结点

    题目描述 输入一个链表,输出该链表中倒数第k个结点.     思路: 法1:设置2个指针p,q.p先移动k次,然后pq同时后移,p到链表尾尾的时候,q指向倒数第k个节点. 注意://需要考虑k=0,以 ...

  8. 【剑指offer】找出数组中出现一次的两个数

    2013-09-08 10:50:46 一个整型数组中,除了两个数字之外,其他数字都出现了2次,找出这两个只出现一次的数字,要求时间复杂度是O(N),空间复杂度是O(1). 小结: 任何数与0异或,结 ...

  9. 剑指Offer:找出数组中出现次数超过一半的元素

    题目:找出数组中出现次数超过一半的元素 解法:每次删除数组中两个不同的元素,删除后,要查找的那个元素的个数仍然超过删除后的元素总数的一半 #include <stdio.h> int ha ...

随机推荐

  1. castle动态代理的使用

    转自:https://blog.csdn.net/educast/article/details/6565447#动态代理的原理 原理其实很简单,就是在运行时生成新的对象,姑且叫做T,并使T继承自需要 ...

  2. HttpWebRequest post 提交 C#的WebBrowser操作frame如此简单 WebClient 提交

    //http://www.cnblogs.com/cgli/archive/2011/04/09/2010497.html System.Net.ServicePointManager.Expect1 ...

  3. c# 匿名函数

    int t(){    Func<int> m=()=>3;    return m()+m();}

  4. flash GC

    所有应用程序都要管理内存.应用程序的内存管理包括用于确定何时分配内存,分配多少内存,何时将内容放入回收站,以及何时清空回收站的准则.MMgc是 Flash Player用于几乎所有内存分配工作的通用内 ...

  5. Linux新增用户过程详解

    Linux系统中,当使用useradd添加用户时,会将系统的/etc/skel目录下的所有文件复制到新添加用户的家目录中.该目录下的所有文件都是隐藏文件(以.点开头的文件). 通过修改.添加.删除/e ...

  6. org.springframework.beans.BeanUtils与org.apache.commons.beanutils.BeanUtils的copyProperties用法区别

    知识点 org.springframework.beans.BeanUtils与org.apache.commons.beanutils.BeanUtils都提供了copyProperties方法,作 ...

  7. Ubuntu 14.04 apt-get更换阿里云源

    https://blog.csdn.net/satomic/article/details/78997611

  8. ubuntu下安装pdf编辑器Master PDF Editor

    在 ubuntu 上看一些 pdf 文档,自带的pdf阅读器不带编辑功能.推荐使用 master pdf editor 1. 安装QT sudo apt-get install qt-sdk 2. 下 ...

  9. ftruncate(改变文件大小)

    ftruncate(改变文件大小) 定义函数 int ftruncate(int fd,off_t length); 函数说明 ftruncate()会将参数fd指定的文件大小改为参数length指定 ...

  10. 重装系统,出现:Units specified don't exist SHSUCDX can't install

    重装系统,出现:Units specified don't exist SHSUCDX can't install 解决方案1: 首先是你的硬盘分区不对吧 先用PQ格成ntfs或far32 进PE把C ...