考察链表的操作,找到单向链表中环的入口节点
C++版
#include <iostream>
#include <algorithm>
using namespace std;
// 定义链表
struct ListNode{
int val;
struct ListNode* next;
ListNode(int val):val(val),next(nullptr){}
};
// 在链表存在环的前提下找到一快一慢两个指针相遇的节点
ListNode* MeetingNode(ListNode* pHead){
if(pHead == nullptr)
return nullptr;
// 定义走的慢节点
ListNode* pSlow = pHead->next;
if(pSlow == nullptr)
return nullptr;
// 定义走的快的节点
ListNode* pFast = pSlow->next;
while(pFast != nullptr && pSlow != nullptr){
if(pFast == pSlow)
return pFast;
// 慢节点走一步
pSlow = pSlow->next;
pFast = pFast->next;
// 快节点走两步
if(pFast->next != nullptr)
pFast = pFast->next;
}
return nullptr;
}
// 找入口节点
ListNode* EntryNodeOfLoop(ListNode* pHead){
ListNode* meetingNode = MeetingNode(pHead);
if(meetingNode == nullptr)
return nullptr;
// 得到环中节点的数目
int nodesInLoop = 1;
ListNode* pNode1 = meetingNode;
while(pNode1->next != meetingNode){
pNode1 = pNode1->next;
nodesInLoop++;
}
// 先移动pNode1,次数为环中节点的数目
pNode1 = pHead;
for(int i = 0; i < nodesInLoop; i++){
pNode1 = pNode1->next;
}
ListNode* pNode2 = pHead;
while(pNode1 != pNode2){
pNode1 = pNode1->next;
pNode2 = pNode2->next;
}
return pNode1;
}
// 更简单的一个办法,只有一个函数解决问题
ListNode* hasCycle(ListNode* pHead){
ListNode* fast = pHead;
ListNode* slow = pHead;
while(fast != nullptr && fast->next != nullptr){
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
break;
}
// 没有环则返回
if(fast == nullptr && fast->next == nullptr)
return nullptr;
slow = pHead;
while(slow != fast){
slow = slow->next;
fast = fast->next;
}
return fast;
}
int main()
{
char *p = "hello";
// p[0] = 'H';
cout<<p<<endl;
return 0;
}