LeetCode---Linked List Cycle、Linked List Cycle II解题分析

题意描述:给定一个单向链表,(1)判断其是否有环;(2)如果有环找出环结点。

解题分析:一个单向链表如果有环,则必然存在最后一个结点的next指针指向链表中其他任意一个结点。如果单从结点上判断,这就相当于一没有尽头的死循环,所以一个指针肯定不行,就想到利用两个指针,然后以不同的速度从起点出发,如果两个指针能够相遇,则说明存在回路(证明就是小时常做的应用题目:小明和小红在操场跑步一个快一个慢,从一次相遇到下一次相遇问题、时针分针相遇问题。。。这里不再证明)。所在判断是否有环的代码如下:

public class LinkedListCycle {//链表结构
	int val;
	LinkedListCycle next;
	LinkedListCycle(int x){
		val = x;
		next = null;
	}
}

boolean hasCycle(LinkedListCycle head){
	LinkedListCycle p,q;
	p = head;//从头开始遍历
	q = head;//从头开始遍历
	while(q != null && q.next != null){
		p = p.next;//一次前进一步
		q = q.next.next;//一次前进两步
		if(q == p)//如果相遇则返回true
			 return true;
	}				
	return false;		
}


在上面的基础上该如何找出环结点呢?

如图所示,第一次相遇是在K结点(相对于环结点),此时指针P走了S1=[X+K+m(K+Y)]步(表示慢赶到K后又指针转了m圈与快指针在K相遇),指针Q走了S2=[X+n(K+Y)+K]步(表示快指针转了n圈后又走了K步与慢指针在K相遇)。由于S2=2*S1,解得:(n-2m)(K+Y) = X+K,(n-2m)为一个常数项,X=(n-2m-1)(Y+K)+Y。所以一个指针从K出发,另一个指针从头出发,再次相遇点就是环结点:

LinkedListCycle detectCycle(LinkedListCycle head){
	LinkedListCycle p,q;
	p = head;
	q = head;
	while(q != null && q.next != null){
		p = p.next;
		q = q.next.next;
		if(p == q)//第一次相遇
			break;
	}
	
	if(q==null || q.next==null)
		return null;
	
	p = head;
	while(p != q){
		p = p.next;
		q = q.next;
	}
	return q;
	
}

这样的题目都是有套路的,如果曾经做过,记住结论就好了,但真正应当做到理解解题原理,能够举一反三!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值