141.环形链表
题目描述
给一个链表的头节点head,判断链表中是否有环
思路
快慢指针,创建两个指针变量fast、slow,fast每次移动两个位置,slow每次移动一个位置,如果链表中有环存在,那么fast指针一定会在将在某个时间与slow相遇在同一节点。
代码实现
/*
* struct ListNode{
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL){}
*};
*/
class Solution{
public:
bool hasCycle(ListNode *head){
//创建快慢指针
ListNode *fast = head;
ListNode *slow = head;
//移动两个指针,如果没有相遇返回false
while(fast && fast->next){
fast = fast->next->next;
slow = slow->next;
// 相遇返回true
if(fast == slow){
return true;
}
}
return false;
}
};
142. 环形链表Ⅱ
题目描述
给定一个链表的头节点head,返回链表开始入环的第一个节点,如果链表无环,返回null。
思路
- 创建快慢指针, 判断有环无环
- 假如有环,快慢指针相遇,
slow走了x距离,fast走了2x距离,多出来的x的距离为fast在环内转圈的长度。 - 设头节点到入环位置的长度为
n, 入环位置距slow指针位置长度为x-n。 - 从fast最终位置再走x- (x-n) 步,也一定能到达入口位置。
- 设置两个指针,分别从head结点和相遇点出发,走过n步会相遇,当两个指针相遇的时候,即为环的入口位置 ,返回此时节点。
- 无环则返回NULL
代码
/*struct ListNode{
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL){}
*};
*/
class Solution{
public:
ListNode *detectCycle(ListNode *head){
ListNode *fast = head;
ListNode *slow = head;
ListNode *index1 = head;
ListNode *index2 = NULL;
while(fast && fast->next){
fast = fast->next->next;
slow = slow->next;
if(fast == slow){
index2 = fast;
break;
}
}
// 如果index2不为空,两个指针同步前进,相交即返回
// 为空直接返回
while(index2){
if(index1 == index2){
break;
}
index1 = index1->next;
index2 = index2->next;
}
return index2;
}
};