一.1.题目(141. 环形链表 - 力扣(LeetCode))
2.题目思考
对于这个题目就是判断是不是环形链表。那么是否可以使用一个指针来进行判断经过同一个点,得出是环形链表吗?答案是:不行。因为如果是环形链表的话,指针会不断循环,那么程序进入会死循环。所以,我们思考使用两个指针,一快一慢,当快指针能遇到慢指针时为环形链表。
此时题目就变成了追击问题
3.代码实现
bool hasCycle(struct ListNode *head) {
struct ListNode*fast=head,*slow=head;
while(fast&&fast->next)
{
fast=fast->next->next;
slow=slow->next;
if(fast==slow)
{
return true;
}
}
return false;
}
二.
1.进一步思考
(1).为什么题目1中一定会相遇,有没有可能会错过,永远追不上?
(2).slow走一步,fast走3步,4步,n步,也一定能追上吗?
(3).为什么一定相遇?有没有可能会错过。
2.进一步分析
问题(1):fast走2步,slow走1步
也就是说,当fast追slow的过程中,距离的变化为N-1,N-2,N-3,---,3,2,1,0。当fast与slow的距离为0时就追上了。
问题(2)(3):假设fast走3步,slow走1步。
我们可以暂时得出一个结论:
1.当N是偶数时第一次就追上了
2.当N是奇数时 ,第一次会错过,进入下一轮
(当c是奇数,也就是c-1是偶数时,追上了;当c是偶数时,也就是c-1是奇数时,追不上)
那么就是同时存在N是奇数且c是偶数时,fast永远追不到slow。
那么这个结论是否正确,我们要使用数学进行计算一下
那么上面的结论可以的出并不正确, N是奇数且c是偶数时的条件不能同时出现,永远追不上的条件不能成立。
因此我们的出新的结论:
1.一定能追上
2.当N是偶数时第一次就追上了
3.当N是奇数时 ,第一次会错过,进入下一轮。
三.1.题目(142. 环形链表 II - 力扣(LeetCode))
2.代码实现
struct ListNode* detectCycle(struct ListNode* head) {
struct ListNode *fast = head, *slow = head;
while (fast && fast->next) {
fast = fast->next->next;
slow = slow->next;
if (slow == fast) {
struct ListNode* meet = slow;
while (meet != head) {
meet = meet->next;
head = head->next;
}
return meet;
}
}
return NULL;
}