思路:
如同??赛跑,这里?不存在偷懒情况。?跑的慢,?跑的快,从同一起点出发,如果链表中存在闭环,?最后一定会跟?相遇!相反则不可能再次相遇。
创建两个指针p1,p2,使它们同时指向链表的表头。
开始遍历,每次遍历使得p1指向下一个节点,p2指向下一个节点的下一个节点。然后比较p1与p2的节点值是否相同,如果相同,则表示存在闭环。
遍历结束后,没有遇到节点值相同,则表示不存在闭环。
算法如下:
/** * 节点 */class Node { constructor(value) { this.next = null this.value = value }}// 创建环形链表const root = new Node(1)const node2 = new Node(2)const node3 = new Node(3)const node4 = new Node(4)const node5 = new Node(5)root.next = node2node2.next = node3node3.next = node4node4.next = node5// 形成环形链表node5.next = node3/** * @description 判断链表中是否有闭环? * @param {Object} list 链表 */function isCycleList(linkedList) { let p1 = linkedList, p2 = linkedList; while (p1 = p1.next, p2 = p2?.next?.next) { if (p2 === p1) return true } return false}const flag = isCycleList(root)console.log(flag); // true
思考题:
如果有闭环,求出环的长度以及出入点?