【算法】判断链表是否有环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/**
* 判断链表是否有环
*
* @author lilou
* @since 2021/6/2
*/
public class Ring {
public static class Node {
private final Integer id;
private final String name;
private Node next;

public Node(Integer id, String name) {
this.id = id;
this.name = name;
}

public Integer getId() {
return id;
}

public String getName() {
return name;
}

public Node getNext() {
return next;
}

public void setNext(Node next) {
this.next = next;
}
}

public static void main(String[] args) {
final Node n1 = new Node(1, "赵云");
final Node n2 = new Node(2, "关羽");
final Node n3 = new Node(3, "张飞");
final Node n4 = new Node(4, "刘备");
final Node n5 = new Node(5, "曹操");
n1.setNext(n2);
n2.setNext(n3);
n3.setNext(n4);
n4.setNext(n5);
n5.setNext(n1);

boolean isRing = isRing2(n1);
System.out.println(isRing);
}

/**
* 方法1:快慢指针
*
* @param n1 节点
* @return 是否有环
*/
private static boolean isRing(Node n1) {
if (n1 == null) {
return false;
}

// 慢指针
Node slow = n1;
// 快指针,从下一个开始
Node fast = n1.getNext();
while (fast != null && fast.getNext() != null) {
if (fast == slow) {
return true;
}
slow = slow.getNext();
fast = fast.getNext().getNext();
}

return false;
}

/**
* 方法2:
* 1个指针原地不动,
* 1个指针一步一步向前搜索
*
* @param n1 节点
* @return 是否有环
*/
private static boolean isRing2(Node n1) {
if (n1 == null) {
return false;
}
// 原地不动
Node notMovePointer = n1;
// 步长为1,向前搜索
Node forwardPointer = n1.getNext();
while (forwardPointer != null) {
if (notMovePointer == forwardPointer) {
return true;
}
forwardPointer = forwardPointer.getNext();
}

return false;
}
}