Niuke.com High-Frequency Algorithm Question Series-BM7-Entry Node of the Ring in the Linked List
Topic description
Given a linked list of length n, if it contains a ring, please find the entry node of the ring of the linked list, otherwise, return null.
See the original title: The entry node of the ring in the BM7 linked list
Solution 1: Double pointer method
Use two pointers, fast and slow. They all start at the head of the linked list. Subsequently, the slow pointer moves backward one position at a time, while the fast pointer moves backward two positions. If there is a ring in the linked list, the fast pointer will eventually meet the slow pointer again in the ring.
If there is an encounter, the distance from the encounter to the entry node is the same as the distance from the head node to the entry node. So reset fast as the head node, and both fast and sow nodes go step by step until they meet, which is the entry node.
For the principle, please refer to: Detailed explanation of the principle of double pointer algorithm
Solution 2: Hash method
Use HashSet to record the nodes in the linked list, and then traverse the linked list nodes:
- If the node in the linked list has appeared in the hash table, it means that the linked list has a ring, and the node is the entry node, and it returns
- If the node in the linked list has not appeared in the hash table, add the current node to the hash table, and then judge the next node
Finally, if there are no duplicate nodes, there is no cycle, and null is returned.
Explanation: The solutions to the high-frequency algorithm problem series of Niuke.com -BM6- to determine whether there is a cycle in the linked list are basically the same.
code
import java.util.HashSet;
public class Bm007 {
/**
* 双指针
*
* @param pHead
* @return
*/
public static ListNode entryNodeOfLoop(ListNode pHead) {
ListNode fast = pHead, slow = pHead;
while (fast != null && fast.next != null) {
// 快指针每次走2步,慢指针每次走1步
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
// 快慢指针相遇,说明链表中有环
break;
}
}
// 如果快指针为null,说明快慢指针没有相遇,无环,返回null
if (fast == null || fast.next == null) {
return null;
}
fast = pHead;
// 与第一次相遇的结点相同速度出发,相遇结点为入口结点
while (fast != slow) {
fast = fast.next;
slow = slow.next;
}
// 快慢指针没有相遇,说明无环
return fast;
}
/**
* 哈希法
*
* @param pHead
* @return
*/
public static ListNode entryNodeOfLoop2(ListNode pHead) {
// 用来记录链表中的结点
HashSet<ListNode> nodes = new HashSet<>();
while (pHead != null) {
// 如果链表中的结点已经出现过,这个结点即为环的入口,返回之
if (nodes.contains(pHead)) {
return pHead;
}
nodes.add(pHead);
pHead = pHead.next;
}
return null;
}
public static void main(String[] args) {
/**
* 测试用例链表结构为有环
* testCaseCycle: 3 -> 2 -> 0 -> -4
* ^ |
* ------------
*/
ListNode head = ListNode.testCaseCycle();
/**
* 测试用例,期望输出: 2
*/
System.out.println(entryNodeOfLoop(head));
System.out.println(entryNodeOfLoop2(head));
}
}
$1.01^{365} ≈ 37.7834343329$
$0.99^{365} ≈ 0.02551796445$
Believe in the power of persistence!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。