Leetcode 141. 环形链表(简单) 142. 环形链表II(简单) 快慢指针判断环形链表
题目:
判定链表中是否含有环
思路:
用两个指针,一个跑得快,一个跑得慢。如果不含有环,跑得快的那个指针最终会遇到 null,说明链表不含环;如果含有环,快指针最终会超慢指针一圈,和慢指针相遇,说明链表含有环。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: bool hasCycle(ListNode *head) { ListNode* slow=head; ListNode* fast=head; while(fast!=NULL&&fast->next!=NULL){ slow=slow->next; fast=fast->next->next; if(slow==fast){ return true; } } return false; } };
题目:
如果链表有环,找出环的起始位置
思路:
当快慢指针相遇时,让其中任一个指针指向头节点,然后让它俩以相同速度前进,再次相遇时所在的节点位置就是环开始的位置
推导:
- 第一次相遇时,假设慢指针
slow走了k步,那么快指针fast一定走了2k步: fast一定比slow多走了k步,这多走的k步其实就是fast指针在环里转圈圈,所以k的值就是环长度的「整数倍」。- 设相遇点距环的起点的距离为
m,那么环的起点距头结点head的距离为k - m,也就是说如果从head前进k - m步就能到达环起点 - 从相遇点继续前进
k - m步,也恰好到达环起点
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *detectCycle(ListNode *head) { ListNode* slow=head; ListNode* fast=head; while(fast!=NULL&&fast->next!=NULL){ 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; } };
联系方式:emhhbmdfbGlhbmcxOTkxQDEyNi5jb20=

浙公网安备 33010602011771号