Skip to content

Commit b95d74c

Browse files
committed
연결리스트 - Two Pointer Technique 2 (Leetcode)
1 parent 9fb24b3 commit b95d74c

File tree

2 files changed

+245
-8
lines changed

2 files changed

+245
-8
lines changed

src/main/java/linkedlist/LinkedListCycle.java

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,49 @@
22

33
public class LinkedListCycle {
44

5+
/**
6+
* Given head, the head of a linked list,
7+
* determine if the linked list has a cycle in it.
8+
*/
59
public boolean hasCycle(ListNode head) {
10+
return findMeetPoint(head) != null;
11+
}
612

13+
/**
14+
* Given a linked list, return the node where the cycle begins.
15+
* If there is no cycle, return null.
16+
* Solve it using O(1) (i.e. constant) memory
17+
*/
18+
public ListNode detectCycle(ListNode head) {
19+
final ListNode met = findMeetPoint(head);
20+
if (met == null) return null;
21+
22+
ListNode fromStart = head;
23+
ListNode fromMet = met;
24+
25+
while (true) {
26+
if (fromStart == fromMet) return fromStart;
27+
fromStart = fromStart.next;
28+
fromMet = fromMet.next;
29+
}
30+
}
31+
32+
private ListNode findMeetPoint(ListNode head) {
733
ListNode faster = head;
834
ListNode slower = head;
935

10-
while (faster != null && faster.next != null) {
11-
36+
while (faster != null) {
1237
faster = faster.next;
13-
if (faster == slower) return true;
38+
if (faster == null) return null;
1439

1540
faster = faster.next;
16-
if (faster == null) return false;
17-
if (faster == slower) return true;
41+
if (faster == null) return null;
1842

1943
slower = slower.next;
44+
if (slower == faster) return slower;
2045
}
2146

22-
return false;
47+
return null;
2348
}
2449

2550
public static class ListNode {

src/test/java/linkedlist/LinkedListCycleTest.java

Lines changed: 214 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
import lombok.val;
44
import org.junit.Test;
55

6-
import static org.junit.Assert.assertFalse;
7-
import static org.junit.Assert.assertTrue;
6+
import static org.junit.Assert.*;
87

98
public class LinkedListCycleTest {
109

@@ -67,4 +66,217 @@ public void hasCycleWhenHeadIsNull() {
6766
assertFalse(hasCycle);
6867
}
6968

69+
@Test
70+
public void detectCycleExample1() {
71+
72+
// given: 3 -> 2 -> 0 -> -4 -> 2(cycle)
73+
val node1 = new LinkedListCycle.ListNode(3);
74+
val node2 = new LinkedListCycle.ListNode(2);
75+
val node3 = new LinkedListCycle.ListNode(0);
76+
val node4 = new LinkedListCycle.ListNode(-4);
77+
node1.next = node2;
78+
node2.next = node3;
79+
node3.next = node4;
80+
node4.next = node2;
81+
82+
// when
83+
val cycle = new LinkedListCycle().detectCycle(node1);
84+
85+
// then
86+
assertNotNull(cycle);
87+
assertEquals(node2, cycle);
88+
}
89+
90+
@Test
91+
public void detectCycleExample2() {
92+
93+
// given: 1 -> 2 -> 1(cycle)
94+
val node1 = new LinkedListCycle.ListNode(1);
95+
val node2 = new LinkedListCycle.ListNode(2);
96+
node1.next = node2;
97+
node2.next = node1;
98+
99+
// when
100+
val cycle = new LinkedListCycle().detectCycle(node1);
101+
102+
// then
103+
assertNotNull(cycle);
104+
assertEquals(node1, cycle);
105+
}
106+
107+
@Test
108+
public void detectCycleExample3() {
109+
110+
// given: 1
111+
val node1 = new LinkedListCycle.ListNode(1);
112+
113+
// when
114+
val cycle = new LinkedListCycle().detectCycle(node1);
115+
116+
// then
117+
assertNull(cycle);
118+
}
119+
120+
@Test
121+
public void detectCycleCustom1() {
122+
123+
// given: 1 -> 2 -> 3 -> 4 -> 5 -> 3
124+
val node1 = new LinkedListCycle.ListNode(1);
125+
val node2 = new LinkedListCycle.ListNode(2);
126+
val node3 = new LinkedListCycle.ListNode(3);
127+
val node4 = new LinkedListCycle.ListNode(4);
128+
val node5 = new LinkedListCycle.ListNode(5);
129+
node1.next = node2;
130+
node2.next = node3;
131+
node3.next = node4;
132+
node4.next = node5;
133+
node5.next = node3;
134+
135+
// when
136+
val cycle = new LinkedListCycle().detectCycle(node1);
137+
138+
// then
139+
assertNotNull(cycle);
140+
assertEquals(node3, cycle);
141+
}
142+
143+
@Test
144+
public void detectCycleCustom2() {
145+
146+
// given: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 3
147+
val node1 = new LinkedListCycle.ListNode(1);
148+
val node2 = new LinkedListCycle.ListNode(2);
149+
val node3 = new LinkedListCycle.ListNode(3);
150+
val node4 = new LinkedListCycle.ListNode(4);
151+
val node5 = new LinkedListCycle.ListNode(5);
152+
val node6 = new LinkedListCycle.ListNode(6);
153+
node1.next = node2;
154+
node2.next = node3;
155+
node3.next = node4;
156+
node4.next = node5;
157+
node5.next = node6;
158+
node6.next = node3;
159+
160+
// when
161+
val cycle = new LinkedListCycle().detectCycle(node1);
162+
163+
// then
164+
assertNotNull(cycle);
165+
assertEquals(node3, cycle);
166+
}
167+
168+
@Test
169+
public void detectCycleCustom3() {
170+
171+
// given: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 4
172+
val node1 = new LinkedListCycle.ListNode(1);
173+
val node2 = new LinkedListCycle.ListNode(2);
174+
val node3 = new LinkedListCycle.ListNode(3);
175+
val node4 = new LinkedListCycle.ListNode(4);
176+
val node5 = new LinkedListCycle.ListNode(5);
177+
val node6 = new LinkedListCycle.ListNode(6);
178+
node1.next = node2;
179+
node2.next = node3;
180+
node3.next = node4;
181+
node4.next = node5;
182+
node5.next = node6;
183+
node6.next = node4;
184+
185+
// when
186+
val cycle = new LinkedListCycle().detectCycle(node1);
187+
188+
// then
189+
assertNotNull(cycle);
190+
assertEquals(node4, cycle);
191+
}
192+
193+
@Test
194+
public void detectCycleCustom4() {
195+
196+
// given: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 4
197+
val node1 = new LinkedListCycle.ListNode(1);
198+
val node2 = new LinkedListCycle.ListNode(2);
199+
val node3 = new LinkedListCycle.ListNode(3);
200+
val node4 = new LinkedListCycle.ListNode(4);
201+
val node5 = new LinkedListCycle.ListNode(5);
202+
val node6 = new LinkedListCycle.ListNode(6);
203+
val node7 = new LinkedListCycle.ListNode(7);
204+
node1.next = node2;
205+
node2.next = node3;
206+
node3.next = node4;
207+
node4.next = node5;
208+
node5.next = node6;
209+
node6.next = node7;
210+
node7.next = node4;
211+
212+
// when
213+
val cycle = new LinkedListCycle().detectCycle(node1);
214+
215+
// then
216+
assertNotNull(cycle);
217+
assertEquals(node4, cycle);
218+
}
219+
220+
@Test
221+
public void detectCycleCustom5() {
222+
223+
// given: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 4
224+
val node1 = new LinkedListCycle.ListNode(1);
225+
val node2 = new LinkedListCycle.ListNode(2);
226+
val node3 = new LinkedListCycle.ListNode(3);
227+
val node4 = new LinkedListCycle.ListNode(4);
228+
val node5 = new LinkedListCycle.ListNode(5);
229+
val node6 = new LinkedListCycle.ListNode(6);
230+
val node7 = new LinkedListCycle.ListNode(7);
231+
val node8 = new LinkedListCycle.ListNode(8);
232+
node1.next = node2;
233+
node2.next = node3;
234+
node3.next = node4;
235+
node4.next = node5;
236+
node5.next = node6;
237+
node6.next = node7;
238+
node7.next = node8;
239+
node8.next = node4;
240+
241+
// when
242+
val cycle = new LinkedListCycle().detectCycle(node1);
243+
244+
// then
245+
assertNotNull(cycle);
246+
assertEquals(node4, cycle);
247+
}
248+
249+
@Test
250+
public void detectCycleCustom6() {
251+
252+
// given: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 8
253+
val node1 = new LinkedListCycle.ListNode(1);
254+
val node2 = new LinkedListCycle.ListNode(2);
255+
val node3 = new LinkedListCycle.ListNode(3);
256+
val node4 = new LinkedListCycle.ListNode(4);
257+
val node5 = new LinkedListCycle.ListNode(5);
258+
val node6 = new LinkedListCycle.ListNode(6);
259+
val node7 = new LinkedListCycle.ListNode(7);
260+
val node8 = new LinkedListCycle.ListNode(8);
261+
val node9 = new LinkedListCycle.ListNode(9);
262+
val node10 = new LinkedListCycle.ListNode(8);
263+
node1.next = node2;
264+
node2.next = node3;
265+
node3.next = node4;
266+
node4.next = node5;
267+
node5.next = node6;
268+
node6.next = node7;
269+
node7.next = node8;
270+
node8.next = node9;
271+
node9.next = node10;
272+
node10.next = node10;
273+
274+
// when
275+
val cycle = new LinkedListCycle().detectCycle(node1);
276+
277+
// then
278+
assertNotNull(cycle);
279+
assertEquals(node10, cycle);
280+
}
281+
70282
}

0 commit comments

Comments
 (0)