ภาพรวมปัญหา
มี Linked List ต้องตรวจสอบว่ามีวงจร (cycle) หรือไม่ ใช้ตัวแปร pos แทนตำแหน่งที่ tail เชื่อมต่อ (pos = -1 หมายถึงไม่มีวงจร) ห้ามแก้ไขโครงสร้างลิสต์
ตัวอย่าง: [5, 3, 2, 0, -4, 7], pos = 1 → tail เชื่อมต่อที่โหนดที่ 2 (ค่า 3)
อัลกอริทึม Floyd's Cycle Detection (Tortoise and Hare)
- slow := head, fast := head
- while slow, fast และ fast->next มีอยู่:
- slow := slow->next
- fast := fast->next->next
- ถ้า slow == fast → break
- ถ้า fast ว่างหรือ fast->next ว่าง → return null (ไม่มีวงจร)
- ถ้า slow == fast:
- slow := head
- while slow != fast: slow := slow->next, fast := fast->next
- return slow (จุดเริ่มต้นของวงจร)
ตัวอย่างโค้ด C++
#include <bits/stdc++.h>
using namespace std;
class ListNode{
public:
int val;
ListNode *next;
ListNode(int data){
val = data;
next = NULL;
}
};
ListNode *make_list(vector<int> v){
ListNode *head = new ListNode(v[0]);
for(int i = 1; i < v.size(); i++){
ListNode *ptr = head;
while(ptr->next != NULL) ptr = ptr->next;
ptr->next = new ListNode(v[i]);
}
return head;
}
ListNode *get_node(ListNode *head, int pos){
ListNode *ptr = head;
if(pos != -1){
int p = 0;
while(p < pos){ ptr = ptr->next; p++; }
return ptr;
}
return NULL;
}
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* slow = head;
ListNode* fast = head;
while(slow && fast && fast->next){
slow = slow->next;
fast = fast->next->next;
if(slow == fast) break;
}
if(!fast || !fast->next) return NULL;
if(slow == fast){
slow = head;
while(slow != fast){
slow = slow->next;
fast = fast->next;
}
}
return slow;
}
};
int main(){
Solution ob;
vector<int> v = {5,3,2,0,-4,7};
ListNode *head = make_list(v);
int pos = 1;
ListNode *lastNode = get_node(head, v.size() - 1);
lastNode->next = get_node(head, pos);
cout << "Tail is connected to the node with value:" << ob.detectCycle(head)->val;
}
Input / Output
Input: [5,3,2,0,-4,7] 1 Output: Tail is connected to the node with value: 3