/*
题目:
	如果链表中包含环,如何找出环的入口?
*/
/*
思路:
	双指针:
		1、判断是否有环。
			fast指针一次2步,slow指针一次1步,当fast与slow相遇时,说明有环。
		2、判断环路中节点的个数。
			当fast和slow相遇的节点在环上,一个指针固定,
			另一个指针循环一周再次遇到该固定指针,遍历的个数即为节点个数。
		3、找到入口节点。
			fast指针先走k步,
			接着,fast和slow指针同时遍历,
			相遇节点即为入口节点。
*/
#include<iostream>
#include<string.h>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;

struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};

int LoopNodeLength(ListNode* pHead){
    int length = 0;
    ListNode* slow = pHead;
    ListNode* fast = pHead->next;
    if(fast == nullptr) return length;

    while(fast->next != nullptr && fast != slow){
        fast = fast->next->next;
        slow = slow->next;
    }
    if(fast->next != nullptr){
        fast = slow->next;
        length = 1;
        while(fast != slow){
            length++;
            fast = fast->next;
        }
    }
    return length;

}
 ListNode* EntryNodeOfLoop(ListNode* pHead)
{
    if(pHead == nullptr) return nullptr;
    int length = LoopNodeLength(pHead);
    if(length == 0) return nullptr;

    ListNode* fast = pHead;
    ListNode* slow = pHead;
    for(int i = 0; i < length; i++){
        fast = fast->next;
    }
    while(fast != slow){
        fast = fast->next;
        slow = slow->next;
    }
    return slow;
}



int main(){
   ListNode* node1 = new ListNode(1);
   ListNode* node2 = new ListNode(2);
   ListNode* node3 = new ListNode(3);
   node1->next = node2;
   node2->next = node3;
   node3->next = node1;
   cout<<EntryNodeOfLoop(node1)->val<<endl;
}

   

posted on 2019-11-20 22:26  笨宝宝  阅读(128)  评论(0编辑  收藏  举报