继续链表算法
有点恍恍惚惚。
题目描述:判断一个单链表是否有环
分析:还是通过快慢指针来解决,两个指针从头节点开始,慢指针每次向后移动一步,快指针每次向后移动两步,如果存在环,那么两个指针一定会在环内相遇。首先单链表有环是什么一种结构呢? 小b这种结构么? 因为只能是单方向的指引,所以应该是小b这种结构。两个指针先后进入环里面,一个比另一个每次快一步,是不是一定会遇上。是的。那么如果快两步呢?就是一个指针每次走3步,另一个每次走一步?相遇的话,快的那个是不是一定领先慢的那个若干个圈的长度?假设经过x步相遇,那么领先2x个节点。所以圈内节点数一定要是偶数才行?先想题目吧。
function linkedListWithCircle(head){
if(head==null||head.next==null) return false;
var fastNode = head;
var normalNode = head;
while(fastNode!=null&&fastNode.next!=null){//只是为了保证可以执行fastNode.next.next操作。避免null.next错误。
fastNode = fastNode.next.next;
normalNode = normalNode.next;
if(normalNode==fastNode) return true;
}
return false;
}
题目描述:判断单链表是否有环,如果有,找到环的入口点
分析:由上题可知,按照 p2 每次两步,p1 每次一步的方式走,发现 p2 和 p1 重合,确定了单向链表有环路了。接下来,让 p2 回到链表的头部,重新走,每次步长不是走 2 了,而是走 1,那么当 p1 和 p2 再次相遇的时候,就是在环路的入口点。加深思考。
function findLoopPort(head){
if(head==null||head.next==null) return null;
var fastNode = head;
var normalNode = head;
var hasCircle = false;
while(fastNode != null&&fastNode.next != null){
fastNode = fastNode.next.next;
normalNode = normalNode.next;
if(normalNode == fastNode) {
hasCircle = true;
break;
}
}
if(!hasCircle) return null;//原本想return false,后来发现还是null好。
var fastNode = head;
while(fastNode != normalNode){
fastNode = fastNode.next;
normalNode = normalNode.next;
}
return fastNode;
}
想画个图来着。还是算了吧。反正走了x步相遇,那么快的领先慢的x步,正好是一圈的长度。
假设从头节点到圈的入口要走m步,那么慢节点在圈内走了x-m步,从相遇的节点到入口节点,差x-(x-m)=m步。
所以如果快节点从头开始和慢节点以一样的一格一格跑,必在入口处相遇。
还是画个图吧。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。