快慢指针指两个移动速度不同的指针,多为2倍关系,快慢指针多用来查找链表中点、判断链表是否为环链、计算环链入口。
查找链表中点
设置快慢两个指针,其中快指针每次移动两个节点、慢指针每次移动一个节点,当快指针到达链表结尾时,慢指针所处的位置即链表中点处,该应用在leetcode109题有考察,简单代码如下:
while (fast&&slow)
{
if (fast->next==NULL)
return slow ->data;
else if (fast->next!= NULL && fast->next->next== NULL)
return (slow ->data + slow ->next->data)/2;
else
{
fast= fast->next;
fast= fast->next;
slow = slow ->next;
}
}
判断链表是否为环链
判断是否为环链的思想很常见,当链表是环链时,快指针总是可以追上慢指针,跟操场上两个速度不同的人跑圈是一样的道理,代码示意如下:
bool isExitsLoop(LinkList *L) {
LinkList *fast, *slow;
fast = slow = L;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
{
break;
}
}
return ((fast == NULL) || (fast->next == NULL));
}
计算环链入口
这里直接搬运别人博客上的内容,
假设慢指针进入环中时,即连接点p,快指针(q)需要m步才能追上慢指针。
p和q第一次相遇时,碰撞点在pq处。此时,p走到pq时用了m步。
假设head到p的距离为a,环长度为Length环,慢指针走了s步,则快指针走了2s步。
从上图可知:
s = a + m
2s = a + m + n * Length环(n为快指针绕环的圈数)
扫描二维码关注公众号,回复:
4651484 查看本文章
可得
a = n * Length环 - m
因此,设n为1,则a = Length环 - m
也就是:若在头结点(head)和相遇结点(pq)分别设一指针,同步(单步)前进,则最后一定相遇在环入口结点p。
代码示意如下:
node* findLoopPort(node *head) {
node *fast, *slow;
fast = slow = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
break;
}
}
if ((fast == NULL) || (fast->next == NULL)) {
return NULL;
}
slow = head;
while (slow != fast) {
slow = slow->next;
fast = fast->next;
}
return slow;
}