题目
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。(测试用例,没什么关系)
示例代码
使用hashset
public boolean hasCycle(ListNode head) {
ListNode curr = head;
HashSet<ListNode> set = new HashSet<>();
while (curr != null) {
if (set.contains(curr)) {
return true;
} else {
set.add(curr);
}
curr = curr.next;
}
return false;
}
要点
- 利用set的不可重复性:每走一步都记录下结点,如果在set中包含了当前节点说明已经走过了,即出现了环
- 时间O(n),空间:借助set,每个节点都要存放,O(n)
注意:泛型中放的是ListNode不是Integer,当时一直犯迷糊,题目也没说结点值一定不重复啊,为啥要用set
使用快慢指针
public boolean hasCycle(ListNode head) {
if (head == null || head.next == null) {
return false;
}
ListNode fast = head;
ListNode slow = head;
while (true) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
return true;
}
if (fast == null || fast.next == null) {
return false;
}
}
}
要点
- 快慢指针:快指针每次走两步,慢指针每次走一步,如果成环,快指针一定会追上慢指针
- 时间:O(n)空间:O(1) (题目要求O(1)空间复杂度,所以第一种就不合适了)
实现很简单,不过一般人不好往这儿想吧,这应该是高级玩家的玩法