【Java】给定一个有环链表,实现算法返回环路的开头结点

假设链表有一部分是环路,一部分不是,环路起始处距离链表表头有K个结点
1. 创建两个指针:FastRunner 和 SlowRunner
public class FindLoopBegining {
	public LinkedListNode FindBeginging(LinkedListNode head){
		LinkedListNode slow = head;
		LinkedListNode fast = head;
		
		while( fast != null && fast.next!= null ) {
			slow = slow.next;
			fast = fast.next.next;
			if (slow == fast) {
				break;
			}
		}
		
		//no collision, no loop
		if (fast == null || fast.next == null) {
			return null;
		}
		
		//slow points to head, fast points to collision spot, 两者以相同速度移动,则必定会碰撞在环路开始处
		slow = head;
		while (slow != fast) {
			slow = slow.next;
			fast = fast.next;
		}
		
		return fast;
	}

}


2. SlowRunner 每走一步, FastRunner走两步,则当SlowRunner进入环路时,FastRunner已经进入环路K个结点后,且这时他们相距LOOP_SIZE-K的结点;此时,SlowRunner每走一个结点,FastRunner就每走两个结点,由于这是一个环路,所以每走一次两者的距离就会更近一个结点。因此在走了LOOP_SIZE-K个结点后两者会碰在一起,而且这时他们距离环路起始处刚好有K个结点。
3. 两者碰在一起时,他们距离环路起始处还有K个结点,将SlowRunner指向LinkedListHead, FastRunner保持不变,这时SlowRunner和FastRunner距离环路起始处均有K个结点

4. 以相同速度移动SlowRunner和FastRunner,一次一步,这两个指针会在此碰到一起,这是在K步之后,而新的碰撞出就是环路的起始结点。然后返回新的碰撞处。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值