剑指offer-----链表中环的入口节点

1、题目描述

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

2、思路

(1)确定链表中是否包含环

定义两个指针,同时从链表的头结点出发,一个指针一次走一步,另一个指针一次走两步,如果走得快的指针追上了走的慢的指针,那么链表就包含环;如果走的快的指针走到了链表的末尾都没有追上走的慢的指针,那么链表就不包含环。

(2)确定环中节点的个数

在(1)中,快慢两个指针相遇时,一定是在环中。可以使慢指针向前移动,快指针不动,当两个节点再次重合时,便可以得到环中节点的数量。

(3)确定环的入口节点

设置两个指针分别指向链表的头结点,假设环中的节点数量是count,一个指针先走count步,然后两个指针一起走,当两个指针重合时,所指向的节点便是环的入口节点。

3、代码实现

/*
 public class ListNode {
    int val;
    ListNode next = null;


    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {


    public ListNode EntryNodeOfLoop(ListNode pHead)
    {
        if(pHead == null){
            return null;
        }
        ListNode fast = pHead;
        ListNode slow = pHead;
        boolean hav = false;
        //统计链表中是否有环
        while(fast != null){
           
            slow = slow.next;
            fast = fast.next;
            if(fast!=null){
                fast = fast.next;
                
            }
            if(fast == slow && fast!=null){
                hav = true;
                break;
            }
            
        }
        int count = 1;
        ListNode node1 = pHead;
        ListNode node2 = pHead;
        if(hav){
                slow = slow.next;
                
            //统计环中的节点数量
            while(slow != fast && slow!=null ){
                slow = slow.next;
                count++;
                
            }
            //设置两个指向头结点的指针,让第一个指针先走count步,然后两个指针一起走
            //当两个指针所指的节点相等时,该节点便是入口节点。
            for(int i=0;i<count;i++){
              
                  node1 = node1.next;
             
            }
            while(node1 != node2 ){
                node1 = node1.next;
                node2 = node2.next;
            }
             return node1;
        }else{
            return null;
        }

    }
}

猜你喜欢

转载自blog.csdn.net/g1607058603/article/details/80977690