1、单链表是否存在环?
根据跑道原理,可以设置两个指针,一快一慢,快的每次前进两步,慢的每次前进一步。
在环中的时候,快的必然可以追上慢的,并且快的不会反超慢的,因为不存在这样的状态
让其反超,快的还差一步追上慢的,继续往前走就追上了慢的,快的还差两部追上慢的,
继续往前走就和慢的相差一步了,依次类推。
bool isExistLoop(slist<int> *head)
{
slist<int> *pslow, *pfast;
pslow = pfast = head;
while(null!=pfast && null!=pfast->next){
pslow = pslow->next;
pfast = pfast->next->next;
if(pfast==pslow) break;
}
return null!=pfast && null!=pfast->next;
}
2.单链表环的入口点?
设链表起点到入口点的位置长度为x,入口点到相遇点长度为y
则慢指针走过的长度 n = x + y
快指针走过的长度为2*n = x + y + k*L (L为环的长度)
有k*L = n,即从相遇点开始走n步可以回到相遇点,而从链表头部走也需要n步到相遇点
这两条路径必然在入口处相遇。动手画一画会比较清楚一点
slist<int> *getLoopPoint(slist<int> *head)
{
slist<int> *pslow, *pfast;
pslow = pfast = head;
while(null!=pfast && null!=pfast->next){
pslow = pslow->next;
pfast = pfast->next->next;
if(pfast==pslow) break;
}
if(null==pfast || null==pfast->next) return null;
pslow = head;
while(pslow != pfast){
pslow = pslow->next;
pfast = pfast->next;
}
return pslow;
}
相关文章: