一个链表中包含环,请找出该链表的环的入口结点。

// test20.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<cstring>
#include<string.h>
#include<deque>
#include <forward_list>

using namespace std;


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

class Solution {
public:
	ListNode* EntryNodeOfLoop(ListNode* pHead)
	{
		if (pHead == NULL) return NULL;
		vector<ListNode*> vec;
		ListNode* list=NULL;
		int flag = 0;
		while (pHead !=NULL)
		{
			vec.push_back(pHead);
			pHead = pHead->next;
			for (int i = 0;i < vec.size();++i)
			{
			//	if (pHead->next == vec[i])//如果pHead->next在之前的数组中,说明存在环
				if (pHead == vec[i])//如果pHead->next在之前的数组中,说明存在环
				{
					list = vec[i];
					flag = 1;
					break;
				}
			}
			if (flag == 1)break;//找到入口节点,结束
		}
		return list;
		
	}
};
int main()
{

	//vector<int> vec = { 49,38,65,97,76,13,27,49};
	Solution so;
	ListNode node1(1);
	ListNode* node01 = &node1;
	node01->next = node01;
	so.EntryNodeOfLoop(node01);
	cout << "入口节点是:" << so.EntryNodeOfLoop(node01)->val << endl;
//	so.print();
	
	return 0;
}

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//上面是第一种方法
//利用了一个栈存放已经访问过的节点,通过判断再访问的节点是否在vec数组中,来判断入口

    // test20.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<cstring>
#include<string.h>
#include<deque>
#include <forward_list>

using namespace std;


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

class Solution {
public:

	ListNode* EntryNodeOfLoop(ListNode* pHead)
	{
		//设置两个节点,访问过的节点的next都是空
		if (pHead == NULL) return NULL;
		ListNode* pre = pHead;
		ListNode* cur = pHead->next;
		if (cur == NULL) return NULL;
		pre->next = NULL;
		while (cur->next!=NULL)
		{
			pre = cur;
			cur = pre->next;
			
			pre->next = NULL;

		}
		return cur;
	}
};
int main()
{

	//vector<int> vec = { 49,38,65,97,76,13,27,49};
	Solution so;
	ListNode node1(1);
	ListNode node2(2);
	ListNode node3(3);
	ListNode node4(4);
	ListNode* node01 = &node1;
	//node01->next = node01;
	//ListNode* node01 = &node1;
	//ListNode* node02 = &node2;
	//ListNode* node03 = &node3;
	//ListNode* node04 = &node4;

	//node01->next = node02;
	//node02->next = node03;
	//node03->next = node04;
	//node04->next = node02;
	
	so.EntryNodeOfLoop(node01);
//	cout << "入口节点是:" << so.EntryNodeOfLoop(node01)->val << endl;
//	so.print();
	
	return 0;
}
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//第二种方法,利用了两个指针,第一个指针访问完节点后,就利用第二个指针,把访问过的节点重置的next值重置为NULL,
//通过判断节点的next的值来判断该节点是否被访问过
原文地址:https://www.cnblogs.com/wdan2016/p/6057540.html