继续链表算法
有点恍恍惚惚。


题目描述:判断一个单链表是否有环

分析:还是通过快慢指针来解决,两个指针从头节点开始,慢指针每次向后移动一步,快指针每次向后移动两步,如果存在环,那么两个指针一定会在环内相遇。首先单链表有环是什么一种结构呢? 小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步。
所以如果快节点从头开始和慢节点以一样的一格一格跑,必在入口处相遇。
还是画个图吧。
图片描述


好多知识不知道
21 声望0 粉丝

想法,每个人都有,每时每刻。想法并不会一直留在脑中,时间会遗忘一切,有必要整理一些东西,记住那时的你。思维是最美的东西,让不同时间的你,用思维对话。(起高了)