一、在一条链中找环
bool judge(int a[])
{//存在返回ture,否则返回false
int slow = 0, fast = 0;
do {
slow = a[slow];
fast = a[a[fast]];
} while (slow != fast && a[fast] == -1);
if (a[fast]==-1)
return false;
return true;
}
思路:定义两个指针,一快一慢。
若存在环,则两指针一定相遇。
二、找环的环头
int Two_num(int a[])
{//存在环返回环头,否则返回-1
int slow = 0, fast = 0;
do {
slow = a[slow];
fast = a[a[fast]];
} while (slow != fast);
if (a[fast]==-1)
return -1;
fast = 0;
do {
slow = a[slow];
fast = a[fast];
} while (slow != fast);
return slow;
}
分析:开始设a,环头设b,第一次相遇设c。
第一次相遇时fast指针的路径为a-b-c+n环,slow的路径为a-c,故a-b-c+n环=2*(a-c),即为a-b=(n-1)环+c-b。
故有fast减速重新出发,第二次相遇一定是b,即环头。