赞
踩
接下来有几个问题需要我们来思考一下:
slow一次走1步,fast一次走2步,他们一定会相遇吗?(slow在走满一圈之前)
假设链表带环,两个指针最后都会进入环,快指针先进环,慢指针后进环。如果是最差情况:两个指针之间的距离刚好就是环的长度,那么当慢指针刚进环时,就和快指针相遇了。若两者相距N,如图所示,此时,两个指针每移动一次,之间距离缩小一步,因为是整数,所以总会缩小到0。
所以它们一定会相遇!
slow一次走1步,fast一次走3步,他们一定会相遇吗?
若第一轮没有追上,那么它们之间就差了-1,fast在前面,那么我们可以看C-1的奇偶,如果C-1是偶数,那么
而如果C-1是个奇数,那么
如果N是奇数,C是偶数,那么就追不上。这个条件是否成立?请证明!
其实这个条件是不存在的,不可能会出现这种情况!
经过分析我们可以知道,当N是奇数,C是偶数的时候,这个式子不成立,所以这种情况一定不存在!所以 slow一次走1步,fast一次走3步,他们一定会相遇!
slow一次走n步,fast一次走m步,他们一定会相遇吗?(m>n>1)
这个和Q2有相似之处。
请证明:
让一个指针slow从链表起始位置开始遍历链表,同时让一个指针fast从判环时相遇点的位置开始绕环运行,注意slow每次走1步,fast每次走1步,最终肯定会在入口点的位置相遇。
速度是二倍关系,那么相同时间里,fast的路程也是slow路程的2倍
得证。
同时这个思路也可以用在Q2的独立思考题里。
通过这个结论,我们就可以找到入口点了!!
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
输入:head = [3,2,0,-4], pos = 1 输出:true 解释:链表中有一个环,其尾部连接到第二个节点。
思路:快慢指针,即慢指针一次走一步,快指针一次走两步,两个指针从链表起始位置开始往后走,如果链表带环则一定会在环中相遇,否则快指针率先走到链表的末尾。
- /**
- * Definition for singly-linked list.
- * struct ListNode {
- * int val;
- * struct ListNode *next;
- * };
- */
- bool hasCycle(struct ListNode *head)
- {
- struct ListNode *faster=head;
- struct ListNode *slow=head;
- //一起走faster走2步 slow走1步--保持相对速度
- while(faster && slow && faster->next)
- {
- faster=faster->next->next;
- slow=slow->next;
- if(slow == faster)
- {
- return true;
- }
- }
- return false;
- }
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
输入:head = [3,2,0,-4], pos = 1 输出:返回索引为 1 的链表节点 解释:链表中有一个环,其尾部连接到第二个节点。
思路:用Q4的结论:
让一个指针slow从链表起始位置开始遍历链表,同时让一个指针fast从判环时相遇点的位置开始绕环运行,注意slow每次走1步,fast每次走1步,最终肯定会在入口点的位置相遇。
- /**
- * Definition for singly-linked list.
- * struct ListNode {
- * int val;
- * struct ListNode *next;
- * };
- */
- struct ListNode *detectCycle(struct ListNode *head)
- {
- struct ListNode *slow=head;
- struct ListNode *fast=head;
- struct ListNode *meet=NULL;
- while(fast && fast->next)
- {
- fast=fast->next->next;
- slow=slow->next;
- if(fast == slow)
- {
- slow=head;
- while(fast != slow)
- {
- slow=slow->next;
- fast=fast->next;
- }
- return fast;
- }
- }
- return NULL;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。