struct ListNode
{
int _val;
ListNode* _pNext;
};
1.判断是否带环
利用一快一慢指针来求解,一个指针走一步,一个指针走两步,若该链表带环则必定会在环中相遇。如果fast->next为NULL则不存在
ListNode* IsHaveCircle(ListNode *pHead)
{
if(pHead==NULL)
return NULL;
ListNode* pN1=pHead;
ListNode* pN2 = pHead;
while(pN2->_pNext && pN2)
{
pN2 = pN2->_pNext->_pNext;
pN1 = pN1->_pNext;
if(pN1 == pN2)
return pN1;
}
return NULL;
}
2.求环的大小
快慢指针相遇时必定是在环中相遇,所以只需要再从相遇点开始遍历链表,知道在此到该相遇节点,其所走过的路程就是环的大小。
int sizeCircle(ListNode* pHead)
{
ListNode* meet = IsHaveCircle(pHead);
if(meet)
{
int count = 0;
ListNode* temp = meet->_pNext;
while(temp!=meet)
{
temp = temp->_pNext;
count ++;
}
return count;
}
return 0;
}
3,.求环的入口点
求环入口点: T——尾长(非环长度),S——慢指针入环到被追上,C——快指针追慢指针多跑的圈。那么,慢指针走的路程为 T+S,快指针走的路程为 T+S+C,可得 2(T+S)=T+S+C,T=C-S,此时,一个指针从起点出发走T步,一个指针从快慢指针相遇点出发走 C-S 步,此时两指针刚好都在入口点。
ListNode* KListNode(ListNode* pHead)
{
ListNode* meet = IsHaveCircle(pHead);
if(meet)
{
ListNode* temp = pHead;
while(temp!=meet)
{
temp = temp->_pNext;
meet = meet->_pNext;
}
}
return NULL;
}