数据结构 检测链表中的循环或循环

 思路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. */

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值