剑指offer_链表中环的入口节点

来源:互联网 发布:回购的护肤品知乎 编辑:程序博客网 时间:2024/06/12 00:24
/*一个链表中包含环,请找出该链表的环的入口结点。已知的关于环的知识点:环在末尾用快慢指针可以判断是否包含环,快慢指针能遇见则包含如果一个结点不在环上但它的下一个结点在环上,则下一个结点是入口节点如何判断一个结点在不在环上?结点在环上的话好判断,因为走一圈还可以再遇到,遇到就返回true不在环上的话,怎么判断?在环上走一圈没遇到就结束,认为不在环上,如何判断已经走了一圈?先找到一个环上的元素,如果遇到该元素两次则证明已经在环上走一圈了O(n^2)时间复杂度太高搞这么复杂,还不如直接用一个辅助数组保存遍历过的结点,第一次遇到之前遍历过的结点则为环的入口,也是O(n^2)剑指offer思路:快指针比慢指针先走p步,p为环上元素个数,然后两个一起走,等快慢指针相遇的结点就是入口如何求p,先找到一个环上的元素,顺着环走一圈,统计元素个数,当再次遇到该元素,则统计结束*/  class ListNode {    int val;    ListNode next = null;    ListNode(int val) {        this.val = val;    }}class  EntryNodeOfLoop{public static ListNode entryNodeOfLoop(ListNode pHead)    {        if (pHead==null)        {return null;        }//寻找环上的一个结点ListNode fast=pHead.next;ListNode slow=pHead;while(fast!=null&&fast!=slow){slow=slow.next;fast=fast.next;if (fast!=null){fast=fast.next;}}ListNode temp=pHead;while (temp.next!=null){//一个结点不在环上但它的下一个结点在环上if (!isInLoop(temp,fast)&&isInLoop(temp.next,fast)){return temp.next;}temp=temp.next;}return null;    }public static boolean isInLoop(ListNode node, ListNode nodeInLoop)    {ListNode temp=node;int count=0;while (temp.next!=node){//第一次遇到环上的结点if (temp.next==nodeInLoop){count++;}//遇到环上的结点不止一次,证明环遍历结束if (count>1){return false;}temp=temp.next;}return true;}public static ListNode entryNodeOfLoop2(ListNode pHead)    {        if (pHead==null)        {return null;        }//寻找环上的一个结点ListNode fast=pHead.next;ListNode slow=pHead;while(fast!=null&&fast!=slow){slow=slow.next;fast=fast.next;if (fast!=null){fast=fast.next;}}//统计环上结点个数int count=1;ListNode temp=fast;while (temp!=null&&temp.next!=fast){count++;temp=temp.next;}//fast先走count步fast=pHead;int i=0;while (i<count&&fast!=null){fast=fast.next;i++;}//fast和slow同时走slow=pHead;while (fast!=null&&slow!=null){if (fast==slow){return fast;}fast=fast.next;slow=slow.next;}return null;    }public static void main(String[] args) {ListNode head=new ListNode(0);ListNode node1=new ListNode(1);ListNode node2=new ListNode(2);ListNode node3=new ListNode(3);ListNode node4=new ListNode(4);ListNode node5=new ListNode(5);head.next=node1;node1.next=node2;node2.next=node3;node3.next=node4;node4.next=node5;node5.next=node2;System.out.println(entryNodeOfLoop2(head).val);}}

原创粉丝点击