Linked List Cycle II Linked List Cycle

地址:https://oj.leetcode.com/problems/linked-list-cycle/

https://oj.leetcode.com/problems/linked-list-cycle/

题意很简单第一题进行判断链表是否有环,第二个问题就是如果链表有环返回链表环的起始点。

判断链表是否有环很简单:在链表相关问题中经常用到这个方法,设定两个指针,一个快一个慢,如果两个指针相交则肯定存在环。

public class Solution {
    	public boolean hasCycle(ListNode head) {
		if(head == null || head.next ==null){
			return false;
		}
		ListNode fast = head;
		ListNode slow = head;
		while(fast!=null && fast.next!=null){
			fast = fast.next.next;
			slow = slow.next;
			if(fast == slow){
				return true;
			}
		}
		return false;
	}

}


第二个问题判断如果链表有环,返回环的起始点。这里需要用到一点点数学推导:(通过简单示意图很明显可以推导)

当fast指针等于slow指针时,slow指针肯定还没有遍历完整个链表,而此时fast指针已经在环内循环了n圈(n>=1),假定从链表头指针开始slow走了s步,则fast走了2s步,fast所走的步数还等于s加上fast指针比slow指针在环内多走的n圈。设环长为r,则:

2s = s + nr;

=>s = nr;

设整个链表长度为L,环的入口结点到相遇结点的距离为x, 起点到环的入口结点的距离为a.

a + x = nr;

=> a + x = (n-1)r + L - a;

=> a = (n-1)r + (L - a - x);

=> 由链表的头结点到环入口结点的距离等于n-1圈环的长度+相遇点到环入口结点的距离,于是,当我们在链表头部和相遇处分别设一指针,每次各走一步,则两指针必定相遇,且相遇的第一个结点即为环的入口结点。实现比较简单:

public class Solution {
        public ListNode detectCycle(ListNode head) {
    	if(head == null || head.next ==null){
			return null;
		}
		ListNode fast = head;
		ListNode slow = head;
		while(fast!=null && fast.next!=null){
			fast = fast.next.next;
			slow = slow.next;
			if(fast == slow){
				break;
			}
		}
		if(fast == null || fast.next == null){
			return null;
		}
		slow = head;
		while(slow != fast){
			slow = slow.next;
			fast = fast.next;
		}
		return slow;
    }	
}


 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值