public class Solution {
public boolean hasCycle(ListNode head) {
List<ListNode> list = new ArrayList<ListNode>();
while (head != null) {
if (list.contains(head)) {
return true;
} else {
list.add(head);
}
head = head.next;
}
return false;
}
}
시간복잡도: O(n²)
list.contains(head) // O(n) 순회
매번 전체 리스트 검색
공간복잡도: O(n)
성능: 471ms
public class Solution {
public boolean hasCycle(ListNode head) {
if (head == null) return false;
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;
}
}
원리:
시각화:
순환 있음:
[1] -> [2] -> [3] -> [4]
↑ ↓
[6] <- [5]
slow: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 3...
fast: 1 -> 3 -> 5 -> 3 -> 5 -> 3...
만남!
public class Solution {
public boolean hasCycle(ListNode head) {
Set<ListNode> visited = new HashSet<>();
while (head != null) {
if (!visited.add(head)) { // O(1) 체크
return true;
}
head = head.next;
}
return false;
}
}
| 방법 | 시간 | 공간 | Runtime |
|---|---|---|---|
| ArrayList | O(n²) | O(n) | 471ms |
| HashSet | O(n) | O(n) | 4ms |
| Two Pointer | O(n) | O(1) | 0ms |
public class Solution {
public boolean hasCycle(ListNode head) {
if (head == null) return false;
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;
}
}
개선: 471ms → 0ms, O(n) 공간 → O(1)
Cycle 감지 = Floyd’s Algorithm
#LeetCode #LinkedList #Cycle #TwoPointer #Easy #FloydAlgorithm