链表返回环的入口节点,若没有就返回null

刷算法题突然遇见这么一道题,对我这种整天在学校不认真听课的学渣来说,这算法根本不会.所以我在此记录下来以供后来参考

题目

对于一个给定的链表,返回环的入口节点,如果没有环,返回null

题目分析:

1)首先判断是否有环,有环时,返回相遇的节点,无环,返回null
2)有环的情况下,求链表的入环节点
head再次从头出发,每次走一步,slow从相遇点出发,每次走一步,再次相遇即为环入口点。

快慢指针法

将两个指针分别放在链表头(X)和相遇位置(Z),并且改为相同速度,则两指针再环开始位置相遇(Y),如图所示
image
X,Y,Z分别表示链表的起始位置,环开始位置,相遇位置,快指针是慢指针速度的两倍
所以我们有以下公式:
快慢指针再Z相遇的时候,慢指针行驶的距离a+b;快指针行驶的路程为a+b+n(b+c);
因此我们有2(a+b)=a+b+n(b+c),所以说a=(n-1)b+nc=(n-1)(b+c)+c;
所以我们看这个化简后的公式得出,两个指针分别放在起始位置和相遇位置,当一个指针运行了距离为a另一个指针恰好走了n-1圈加上一个c的距离

public ListNode detectCycle(ListNode head) {
        
        if(head==null||head.next==null){
            return null;
        }
        
	//通过快慢指针查找相遇点
        ListNode low = head; //快指针
        ListNode fast = head;  //慢指针
		
        //这里的条件就是判断快指针不能为空
        while(fast!=null&&fast.next!=null){
            low = low.next;
            fast = fast.next.next;
            
		//快慢指针相遇,说明有环
            if(low==fast){
		//在此从头出发
                ListNode tmp = head;
	  //再次相遇的地方就是环的入口点,两个人每次都是走一步
              while(low!=tmp){
                  low = low.next;
                  tmp = tmp.next;
                  
              }
                return low;
        }   
    }
          return null;
    }
posted @ 2021-04-14 23:01  Diamond-fz  阅读(225)  评论(0编辑  收藏  举报