题目描述

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

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

另一个直觉是判断链表有环的算法中出现过的策略,分别按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. JavaScript中的栈和堆内存,作用域

    1.栈 stack”和“堆 heap”            简单的来讲,stack上分配的内存系统自动释放,heap上分配的内存,系统不释放,哪怕程序退出,那一块内存还是在那里.stack一般是静态 ...

  2. 从池子里的beta看秋香, 个性迥异

    从池子里的beta看秋香, 个性迥异 前文里那十只个股为例, 统计了它们的beta值. 回顾如下: Num name code Beta 0 深圳燃气 601139 0.710 公用事业 1 分众传媒 ...

  3. AVL树的JAVA实现及AVL树的旋转算法

    1,AVL树又称平衡二叉树,它首先是一颗二叉查找树,但在二叉查找树中,某个结点的左右子树高度之差的绝对值可能会超过1,称之为不平衡.而在平衡二叉树中,任何结点的左右子树高度之差的绝对值会小于等于 1. ...

  4. VUE2.0 饿了吗视频学习笔记(四):颜色、跳转、设置、vue-resource

    https://gitee.com/1981633/vue_study.git 源码下载地址,随笔记动态更新中 1.设置选中项颜色 <template> <div id=" ...

  5. Winform程序双向绑定

    程序比较简单,一看就明白,主要需要实现INotifyPropertyChanged using System; using System.Collections.Generic; using Syst ...

  6. 2 Player and N Coin

    class Solution { public void printChoices(int[] A, int[][] C) { System.out.println("硬币列表如下:&quo ...

  7. ubuntu新建组合用户命令不管用

    当我们新建了组和用户的时候发现一些命令不管用了,这是什么问题呢. 一.解决方案. 通过以下命令添加组和用户,切换到新用户,发现命令不管用,只有一个$符号. groupadd 新组名 ----添加组 u ...

  8. Linux - sort 排序

    -t # 指定排序时所用的栏位分隔字符 -n # 依照数值的大小排序 -r # 以相反的顺序来排序 -f # 排序时,将小写字母视为大写字母 -d # 排序时,处理英文字母.数字及空格字符外,忽略其他 ...

  9. matplotlib-2D绘图库

    安装  python -m pip install matplotlib  允许中文: 使用matplotlib的字体管理器指定字体文件 plt.rcParams['font.sans-serif'] ...

  10. mysql 架构~mgr具体细节分析

    一 简介:今天咱们来聊聊mgr的具体实现细节 二 关于多点写入的锁冲突问题以及处理:   certify模块主要负责检查事务是否允许提交,是否与其它事务存在冲突,如两个事务可能修改同一行数据.在单机系 ...