思路1 :
使用哈希检测链表中的循环:
这个想法是在哈希图中插入节点,每当遇到哈希图中已经存在的节点时,都会返回 true。
请按照以下步骤解决问题:
- 单独遍历列表,并继续将节点地址放入哈希表中。
- 在任何时候,如果达到 NULL,则返回 false
- 如果下一个当前节点指向 Hash 中以前存储的任何节点,则返回 true。
- 时间复杂度:O(N),只需要遍历一次循环。
辅助空间:O(N),N 是在哈希图中存储值所需的空间。
// Java program to detect loop in a linked list
import java.util.*;
public class LinkedList {
static Node head; // head of list
/* Linked list Node*/
static class Node {
int data;
Node next;
Node(int d)
{
data = d;
next = null;
}
}
/* Inserts a new Node at front of the list. */
static public void push(int new_data)
{
/* 1 & 2: Allocate the Node &
Put in the data*/
Node new_node = new Node(new_data);
/* 3. Make next of new Node as head */
new_node.next = head;
/* 4. Move the head to point to new Node */
head = new_node;
}
// Returns true if there is a loop in linked
// list else returns false.
static boolean detectLoop(Node h)
{
HashSet<Node> s = new HashSet<Node>();
while (h != null) {
// If we have already has this node
// in hashmap it means there is a cycle
// (Because you we encountering the
// node second time).
if (s.contains(h))
return true;
// If we are seeing the node for
// the first time, insert it in hash
s.add(h);
h = h.next;
}
return false;
}
/* Driver program to test above function */
public static void main(String[] args)
{
LinkedList llist = new LinkedList();
llist.push(20);
llist.push(4);
llist.push(15);
llist.push(10);
/*Create loop for testing */
llist.head.next.next.next.next = llist.head;
if (detectLoop(head))
System.out.println("Loop Found");
else
System.out.println("No Loop");
}
}
// This code is contributed by Arnav Kr. Mandal.
思路2:
使用快慢指针
此算法用于在链表中查找循环。它使用两个指针,一个指针的移动速度是另一个指针的两倍。较快的指针称为较快指针,另一个称为慢指针。
请按照以下步骤解决问题:
- 使用两个指针遍历链表。
- 将一个指针 (slow_p) 移动一个指针,将另一个指针 (fast_p) 移动两个指针。
- 如果这些指针在同一节点相遇,则存在循环。如果指针不相遇,则链表没有循环。
时间复杂度:O(N),只需要遍历一次循环。
辅助空间:O(1)。
// Java program to detect loop in a linked list
import java.io.*;
class LinkedList {
Node head; // head of list
/* Linked list Node*/
class Node {
int data;
Node next;
Node(int d)
{
data = d;
next = null;
}
}
/* Inserts a new Node at front of the list. */
public void push(int new_data)
{
/* 1 & 2: Allocate the Node &
Put in the data*/
Node new_node = new Node(new_data);
/* 3. Make next of new Node as head */
new_node.next = head;
/* 4. Move the head to point to new Node */
head = new_node;
}
void detectLoop()
{
Node slow_p = head, fast_p = head;
int flag = 0;
while (slow_p != null && fast_p != null
&& fast_p.next != null) {
slow_p = slow_p.next;
fast_p = fast_p.next.next;
if (slow_p == fast_p) {
flag = 1;
break;
}
}
if (flag == 1)
System.out.println("Loop Found");
else
System.out.println("No Loop");
}
/* Driver program to test above functions */
public static void main(String args[])
{
LinkedList llist = new LinkedList();
llist.push(20);
llist.push(4);
llist.push(15);
llist.push(10);
/*Create loop for testing */
llist.head.next.next.next.next = llist.head;
llist.detectLoop();
}
}
/* This code is contributed by Rajat Mishra. */