链表:寻找环的起点

    给定一个链表,寻找其中环的起点,如果不存在环,则返回null

    

    思路:设置两个指针,前一个每步向前移动两个节点,后一个每步移动一个节点,如果存在环,那么两个指针将会在环中相遇。假设相遇时,后一个指针移动了k步,那么前一个指针就移动了2k步。设链表到环的起点之间的步数为s,从环的起点到相遇点的步数为m,整个环的长度为r,那么在第一次两个指针相遇的时候,后一个指针所走的步数为k=s+m+ar,其中a为指针在环中循环的次数;而前一个指针走过的步数为2k=s+m+br,b是指针在环中循环的次数,由上面两个式子知s+m=(b-2a)r => s=(b-2a)r-m。于是,如果一个指针从链表头开始出发,另一个指针从相遇点开始出发,当第一个指针到达环的起点时,第二个指针也会刚好循环回到环的起点,所以,当这两个指针相遇时的点就是环的起点。

public ListNode detectCycle(ListNode head) {
		if(head == null || head.next == null)
			return null;
        ListNode fast = head;
        ListNode slow = head;
        ListNode p = head;
        while(fast.next != null || fast.next.next != null){
        	if(fast == slow){//meet at slow
        		while(p != slow){
        			p = p.next;
        			slow = slow.next;
        		}
        		return p;
        	}
        	fast = fast.next.next;
        	slow = slow.next;
        }
        return null; //meet the end of the list
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值