有一个单向链表,链表当中有可能出现“环”。
力扣题:141 .Linked List Cycle 环形链表
判断出这个链表是否有环?
方法一:
传统的方法:
- 遍历单链表的每一个节点,每遍历一个新的节点,就从头检查新节点之前的所有节点,用新节点和此节点之前所有节点依次作比较。
- 如果发现新节点之前的所有节点当中存在相同节点ID,则说明该节点被遍历过两次,链表有环;
- 如果之前的所有节点当中不存在相同的节点,就继续遍历下一个新节点,继续重复刚才的操作。
- 时间复杂度:O(n²) 空间复杂度:O(1)
方法二:
- 首先创建一个以节点ID为键的HashSet集合,用来存储曾经遍历过的节点。
- 从头节点开始,依次遍历单链表的每一个节点。每遍历到一个新节点,就用新节点和HashSet集合当中存储的节点作比较
- 如果发现HashSet当中存在相同节点ID,则说明链表有环
- 如果HashSet当中不存在相同的节点ID,就把这个新节点ID存入HashSet
- 之后进入下一节点,继续重复刚才的操作。
- 时间复杂度:O(n) 空间复杂度:O(n)
public class Solution {
public ListNode detectCycle(ListNode head) {
HashSet<ListNode> hashSet = new HashSet<>();
ListNode dummyHead = new ListNode(-1);
dummyHead.next = head;
ListNode cur = dummyHead;
while(null != cur.next){
if(hashSet.contains(cur.next)){
return cur.next;
}
cur = cur.next;
hashSet.add(cur);
}
return null;
}
}
方法三:
- 首先创建两个指针1和2(在java里就是两个对象引用),同时指向这个链表的头节点。
- 然后开始一个大循环,在循环体中,让指针1每次向下移动一个节点,让指针2每次向下移动两个节点,然后比较两个指针指向的节点是否相同。
- 如果相同,则判断出链表有环,如果不同,则继续下一次循环。
- 时间复杂度:O(n) 空间复杂度:O(1)
public class Solution {
public ListNode detectCycle