判断链表中是否有环
题目:
思路:
操作一:定义了两个变量来记录,A一个一次走一步,B一个一次走两步,如果有环B必然会追上A。如果无环B必然会先遍历完。
操作二:定义了一个哈希集合来记录节点指针的哈希值,因为java中对于这8种基本数据类型的变量,变量直接存储的是“值”。而对于非基本数据类型的变量,在一些书籍中称作为 引用类型的变量。引用类型的变量存储的并不是 “值”本身,而是于其关联的对象在内存中的地址。
代码示例:
import java.util.HashSet;
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
public class Solution {
public static void main(String[] args) {
ListNode s = new ListNode(5); //这里只是简单的定义了一个节点,实际应该自己尝试着去做一个链条,或有环或无环
System.out.println(hasCycle1(s));
}
/**
* 操作二,空间复杂度为O(n),定义了一个哈希集合来记录节点指针的哈希值
*
* @param head
* @return
*/
public static boolean hasCycle2(ListNode head) {
HashSet<ListNode> set = new HashSet<ListNode>();
ListNode p = head;
while (p != null) {
if (set.contains(p)) {
return true;
} else {
set.add(p);
}
p = p.next;
}
return false;
}
/**
* 操作一,空间复杂度为O(1),因为只定义了两个变量来记录,A一个一次走一步,B一个一次走两步,如果有环B必然会追上A。如果无环B必然会先遍历完
*
* @param head
* @return
*/
public static boolean hasCycle1(ListNode head) {
if (head == null || head.next == null)
return false;
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (fast == slow) {
return true;
}
}
return false;
}
}