1. 给定一个链表,判断链表中是否有环。
判断一个链表是否有环本质就是一个追一个跑,看是否能追上的问
解题思路: 借助快慢指针来完成追赶问题
定义两个指针(快指针和慢指针),两个指针均从表头的位置开始向后走, 一个走一步, 一个走两步, 如果带环那么一定会相遇。否则快指针就会遍历完二者还没有相遇, 快指针走到空的位置。
class Solution {
public:
bool hasCycle(ListNode *head) {
if(head == NULL)
return false;
ListNode *slow = head;
ListNode *fast = head;
while (fast && fast->next && slow) {
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
return true;
}
return false;
}
};
2. 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
class Solution {
public:
//寻找相遇点的函数
ListNode *Node(struct ListNode *head) {
ListNode *fast, *slow;
if (head == NULL) {
return NULL;
}
fast = slow = head;
while (fast && fast->next) {
fast = fast->next->next;
slow = slow->next;
if (fast == slow)
return fast;
}
return NULL;
}
ListNode *detectCycle(ListNode *head) {
ListNode * cur = Node(head); //寻找相遇的点
//寻找入环的节点
while (cur) {
// while (cur != head) { //假如相遇的点不等于头结点时,那么cur和head继续往后走
// cur = cur->next;
// head = head->next;
// }
// return cur;
if(cur == head) //看相遇的点是不是头结点; 进行比较
return cur;
else
cur = cur->next;
head = head->next;
}
return NULL;
}
};
面试常考:
- 为什么慢指针走一步,快指针走两步,他们就一定会在环中相遇,会不会一直不相遇,一直在追赶?
假如快慢指针同时入环时, 在追赶的过程中,快指针走两步,慢指针走一步,每走一次他们治安近的距离就会缩短,直到他们相遇。 - 为什么慢指针走一步,快指针走三步,不会一直不相遇,而是一直在追赶打转?
当慢指针走一步,快指针走三步时:若慢指针进环时与快指针的距离为奇数时,并且环的周长是偶数时,他们会一直在环中打转, 永远不会相遇
当慢指针走一步,快指针走三步时:若慢指针进环时与快指针的距离为偶数时,并且环的周长是偶数时,他们会一直在环中打转, 永远不会相遇