标签:单链表
给定一个单链表,只给出头指针h:
1、 如何判断是否存在环?
证明:
slow首次在A点进入环路时,fast一定在环中的B点某处。设此时slow距head长为x,B点距A点长度为y,环周长为s。因为fast和slow的步差为1,所以slow前行距离为y的时候,恰好会被fast在M点追上。因为y<s,所以slow尚未完成一次遍历。
//判断单链表是否有环 public static boolean hasCycle(ListNode head) { if(head == null || head.next == null){ return false; } ListNode slow = head; ListNode fast = head; while(fast.next != null && fast.next.next != null){ fast = fast.next.next; slow = slow.next; if(fast == slow){ return true; } } return false; }
2、 如何知道环的长度?
证明:(有公式所以截图了)
//返回环的长度 public static int cycleLength(ListNode head) { if(head == null || head.next == null){ return 0; } ListNode slow = head; ListNode fast = head; while(fast.next != null && fast.next.next != null){ fast = fast.next.next; slow = slow.next; if(fast == slow){ fast = fast.next.next; int length = 2; while(fast != slow){ fast = fast.next.next; length = length + 2; } return length; } } return 0; }
3、 如何找出环的连接点在哪里?
证明:在fast和slow第一次相遇的时候,假定slow走了n步骤,环路的入口是在x步的时候经过的,那么有
slow走的路径: x+y = n; y为fast和slow相交点M距离环路入口的距离
fast走的路径: x+y+k*s = 2*n; s为环路的周长,k是整数
所以得出 n = k*s;
显然,如果从x+y点开始,slow再走n步的话,还可以回到x+y这个点(绕了k圈)
同时另一个指针temp从头开始走的话,经过n步,也会达到x+y这点
两者都减去y步,可知两者走x步必然会在环路的入口点处相遇
//找出环的起始点在哪里 public static ListNode getCycleStartNode(ListNode head) { if(head == null || head.next == null){ return null; } ListNode slow = head; ListNode fast = head; while(fast.next != null && fast.next.next != null){ fast = fast.next.next; slow = slow.next; if(fast == slow){ fast = head; while(fast != slow){ fast = fast.next; slow = slow.next; } return slow; } } return null; }
4、带环链表的长度是多少?
证明:总长度 = s + x;
//带环链表总长度,0表示没环 public static int getListLength(ListNode head) { if(head == null || head.next == null){ return 0; } ListNode slow = head; ListNode fast = head; while(fast.next != null && fast.next.next != null){ fast = fast.next.next; slow = slow.next; if(fast == slow){ ListNode p = slow;//标记相遇的地方 fast = head; int lengthX = 0; int lengthS = 0; while(fast != slow){ fast = fast.next; slow = slow.next; lengthX++; } lengthS = lengthX; while(slow != p){ slow = slow.next; lengthS++; } return lengthX+lengthS; } } return 0; }
标签:单链表
原文地址:http://blog.csdn.net/jingshuigg/article/details/24885627