LeetCode 142. 单链表如何寻找环的入口点(绝对是史上最简单的解法!)
关于带环单链表找入环点的问题,这个问题确实挺难的,网上的大多数解法都看不懂。研究了一下发现了一个更好的解法,其实算法并不是太难,就是得稍微推导一下。以下是推导过程:
package com.xxx;public class MySingleListImpl { class Node { private int data; private Node next; public Node(int data) { this.data = data; this.next = null; } public int getData() { return this.data; } } private Node head; public MySingleListImpl() { this.head = null; }//头插法 public void addFirst(int data) { Node node = new Node(data); if (this.head == null) { this.head = node; }else { node.next = this.head; this.head = node; } }//尾插法 public void addLast(int data) { Node node = new Node(data); if (this.head == null) { this.head = node; }else { Node cur = this.head; while (cur.next != null) { cur = cur.next; } cur.next = node; } }//打印链表 public void display() { Node cur = this.head; while (cur != null) { System.out.print(cur.data + " "); cur = cur.next; } System.out.println(); } //创建一个有环的链表 public void createLoop() { Node cur = this.head; while (cur.next != null) { cur = cur.next; } cur.next = this.head.next.next; } //寻找环的入口点 public Node detectCycle() { Node fast = this.head; Node slow = this.head; //循环退出两种情况: //1.fast.next == null(找到单链表结尾也没有找到环); 2.fast == slow(有环) while (fast.next != null) { fast = fast.next.next; slow = slow.next; if (fast == slow) { break; } } //链表没有环的情况 if (fast.next == null) { return null; } //链表有环 slow = this.head; while (fast != slow) { fast = fast.next; slow = slow.next; } return slow; }}
package com.xxx;public class Test { public static void main(String[] args) { MySingleListImpl list = new MySingleListImpl(); list.addFirst(134); list.addFirst(20); list.addFirst(35); list.addLast(10); list.addLast(999); list.addLast(7); System.out.print("原链表:"); list.display(); list.createLoop(); MySingleListImpl.Node cur = list.detectCycle(); System.out.println("链表入环点是:" + cur.getData()); }}
如果各位大佬有更好的解法,请速速联系我!