环形链表
Leetcode:142,https://leetcode-cn.com/problems/linked-list-cycle-ii/)
1.问题描述
给定一个链表,如果有环路,找出环路的开始点。
2.输入输出
- Input:head = [3,2,0,-4], pos = 1
- Output:1
3.算法分析
【快慢指针】使用两个指针,fast 与 slow。它们起始都位于链表的头部。随后,slow 指针每次向后移动一个位置,而fast 指针向后移动两个位置。如果链表中存在环,则 fast 指针最终将再次与slow 指针在环中相遇。
- 时间复杂度:O(N)
- 空间复杂度:O(1)
4.编程实现
#include <iostream>
#include <vector>
using namespace std;
struct ListNode{
int val;
ListNode *next;
ListNode(int x) : val x, next(nullptr) {}
};
//从头到尾打印链表
vector<int> printListArray(ListNode *head){
vector<int> printList;
while(head){
printList.push_back(head->val);
head = head->next;
}
reverse(printList.begin(), printList.end());
return printList;
}
//检测环路
ListNode *detectCycle(ListNode *head){
ListNode *slow = head, *fast = head;
//判断是否存在环路
do {
if (!fast || !fast->next) return nullptr;
fast = fast->next->next;
slow = slow->next;
}while(fast != slow);
//如果存在,查找环路节点
fast = head;
while(fast != slow){
slow = slow->next;
fast = fast->next;
}
return fast;
}
int main(){
ListNode *head = NULL, *p, *q;
}