链表中环的入口结点

剑指 offer

题目描述

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

思路:

  1. 先判断链表中有环,如果一个链表中有环,那么用两个指针,一个每次移动一个,另外一个指针每次移动两个,那么他们一定会相遇。如果没有环,移动快的那个结点会先指到末尾的 null。
  2. 如果判断链表中有环后,统计环中结点的个数 num。
  3. 使用两个指针,一个指针向后移动 num 个结点,另一个指针指向头,然后两个指针一起移动,当两个指针相遇时则这个结点就是入口结点。

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

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

    public ListNode EntryNodeOfLoop(ListNode pHead)
    {
        ListNode meetNode=meetingNode(pHead);
        if(meetNode==null){
            return null;
        }
        //统计环中个数
        int num=1;
        ListNode nextNode=meetNode.next;
        while(nextNode!=meetNode){
            num++;
            nextNode=nextNode.next;
        }
        ListNode first=pHead,second=pHead;
        for(int i=1;i<=num;i++){
            first=first.next;
        }
        while(first!=second){
            first=first.next;
            second=second.next;
        }
        return first;
        
    }
    //如果存在环则找环中的结点
    public ListNode meetingNode(ListNode pHead){
        if(pHead==null){
            return null;
        }
        ListNode secondNode=pHead.next;
        if(secondNode==null){
            return null;
        }
        ListNode firstNode=secondNode.next;
        
        while(firstNode!=null && secondNode!=null){
            if(firstNode==secondNode){
                return firstNode;
            }
            secondNode=secondNode.next;
            firstNode=firstNode.next;
            if(firstNode!=null){
                firstNode=firstNode.next;
            }
        }
        return null;
    }
    
    
}
posted @ 2018-07-25 11:29  罗贱人  阅读(140)  评论(0编辑  收藏  举报