[编程题] nk:[链表中的入环节点] (快慢指针和哈希表方法)
链表中环的入口结点
http://www.nowcoder.com/questionTerminal/253d2c59ec3e4bc68da16833f79a38e4
[编程题] nk:链表中的入环节点
题目描述
题解参考我博客:https://www.cnblogs.com/jiyongjia/p/13359591.html
输入输出例子
无
思路
方法1、借助哈希表
思想:我们通过一个dummyNode不断遍历每一个节点,当我们每次遍历到这个当前节点的时候就看他在不在哈希表中,不在的话加入进去;在的时候就恰好这个节点就是入环节点。
时间复杂度:O(n)
Java代码
import java.util.*; /* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } */ public class Solution { //方法1:借助哈希表; //思想:每次遍历一个节点,就放入到哈希表,如果再次发现哈希表中有这个节点的时候就是环的入口 public ListNode EntryNodeOfLoop(ListNode pHead){ //跑龙套节点 ListNode dummyNode = pHead; //哈希表 HashSet<ListNode> hashSet = new HashSet<ListNode>(); while(dummyNode!=null){ if(hashSet.contains(dummyNode)){ return dummyNode; //找到入环点 } hashSet.add(dummyNode); //否则放入哈希表 dummyNode = dummyNode.next; } //退出循环,即为找到入环点,无环 return null; } }
输出的效率:
方法2:快慢指针
思想:
总结思想:
- 第一趟跑的时候找相遇点(定义fast=phead.next; slow = phead;错开的好)
- 找到相遇点计算环长
- 重新定义快慢指针指向,pFast指向phead,pSlow指向pHead后的环长n的位置;同时以step=1走
- 相遇即返回该节点为入环点。
时间复杂度O(n)
Java代码
//方法2:快慢指针(第一次快慢速度2:1找到相遇点,计算环长,第二次同步速度走,在入环点相遇) public ListNode EntryNodeOfLoop(ListNode pHead){ //需要考虑只有一个节点的边界情况 if(pHead==null) {return null;} //快慢指针 ListNode pFast = pHead.next; //注意一开始让快慢指针错开,因为不错开的话,在第一次相遇点的逻辑中直接if比较返回相等。返回的就是首节点相遇 ListNode pSlow = pHead; //标注是否有环 boolean isCircle = false; //计算环长的计数器 int count=1; //1 第一次走找是否有环和相遇点 while(pFast!=null && pFast.next!=null){ if(pFast==pSlow){ //在初始快慢指针赋值的时候让错开,不然在这里会返回首节点相遇的 isCircle = true; break;//一定记得有环了跳出while } //否则快指针2倍速走,慢指针1倍速走 pFast = pFast.next.next; pSlow = pSlow.next; } //2 检测isCircle字段看是否有环,有环的话就计算环长 if(!isCircle){ return null;//无环 }else{//有环 //2.1 让快指针从相遇点再绕环走一圈,计算环长 pFast = pFast.next; while(pFast!= pSlow){ count++; //这里while内用的dummyFast.next,故计算的count还差最后一步。 pFast = pFast.next; } } //3 我们得出了环长count值,重新把指针重新指向,快慢指针以step=1开始走,相遇就是入环点 pFast = pSlow = pHead; //退出while后就是找到slow应该指向的节点的地方 while(count>0){ pSlow = pSlow.next; count--; } while(pFast!=pSlow){ pFast = pFast.next; pSlow = pSlow.next; } //退出while,返回的节点就是相遇点 return pFast; }
时间复杂度 :O(n)
输出: