java数据结构与算法之链表找环入口

Posted wen-pan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java数据结构与算法之链表找环入口相关的知识,希望对你有一定的参考价值。

java数据结构与算法之链表找环入口

方法一:使用hash表的方式

  • 首先先遍历这个链表节点,遍历的同时将该节点放入到hashset集合中去。
  • 遍历每个节点的同时去set集合里看看该节点是否存在,如果存在则存在环,并且该节点就是环的入口节点。
public static SingleNode hasCycle2(final SingleNode head) {
  if (head == null || head.next == null) {
   	return null;
  }
  final HashSet<SingleNode> hashSet = new HashSet<>();
  SingleNode current = head;
  while (current != null) {
     // 一边遍历链表一边判断该节点是否在set集合中,如果在则说明有环,并且该节点就是环的入口节点
     // 如果不在并且链表已经遍历完了,则说明没环
     if (hashSet.contains(current)) {
       return current;
     }
     hashSet.add(current);
     current = current.next;
  }
  return null;
}

方法二:使用快慢指针来解决

判断单链表是否有环:

  • 快慢指针都从头节点开始,快指针一次走两步,慢指针一次走一步,当快指针走到的节点为空或快指针的next节点为空则说明该链表无环。
  • 若快指针和慢指针相遇了,则说明该单向链表有环。

如何找到入环节点呢?

  • 当快慢指针相遇了,此时再将快指针指到链表头节点
  • 快慢指针重新开始走,快指针每次走一步,慢指针每次走一步,直到快慢指针再次相遇,相遇的节点就是该单链表的入环节点(可自己去证明)。
public static SingleNode singleListFindCycleNode(final SingleNode head) {
        if (head == null || head.next == null) {
            return null;
        }
        // 两个指针同时从头开始走
        SingleNode fast = head;
        SingleNode slow = head;

        while (fast != null && fast.next != null) {
            // 慢指针一次走一步
            slow = slow.next;
            // 快指针一次走两步
            fast = fast.next.next;
            if (slow == fast) {
                break;
            }
        }

        if (fast == null || fast.next == null) {
            return null;
        }

        // 快指针从头开始重新走,直到他们相遇的节点就是环的入口节点(可自己证明)
        fast = head;
        while (fast != slow) {
            fast = fast.next;
            slow = slow.next;
        }
  			// 返回入环节点
        return fast;
    }

以上是关于java数据结构与算法之链表找环入口的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法(Java)之链表

Leetcode287. Find the Duplicate Number(快慢指针+链表找环的起点)

Leetcode287. Find the Duplicate Number(快慢指针+链表找环的起点)

JAVA数据结构与算法之链表

java数据结构与算法之链表相交问题

java之数据结构之链表及包装类包