Linked List Cycle II (Java)

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Follow up:
Can you solve it without using extra space?

先用一个指针走一步,另一个指针走两步的方法判断是否存在回路,如果存在,则将其中一个指针指回头结点,然后两个指针一步一步往下走,走到相遇的地方,就是指针环路所在节点。

这个问题就好像是追及问题:


两个小人都从A地出发,一个走的速度是另一个的两倍,走的快的人在跑道上绕了n圈后和走的慢的在B地相遇(跑道长度为k),此时可以列出等式:vt + nk = 2vt (nk是速度快的小人多走的路程),那么可得vt = nk,由于慢的小人从A到B总共走了vt,所以可得 l1 + l2 = nk。 本题问的是环路所在节点,即图中红色部分,所以接着推导上式: l1 + l2 = (n - 1)k + k 即 l1 = (n - 1)k + (k - l2)。 k - l2 即为从B点绕跑道逆时针跑到红点的距离,那么可得出一个指针从A点跑,另一个指针从B点跑,此时他们用一样的速度vt,总能在红点处相遇。

Source

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
    	if(head == null || head.next == null) return null;
    	
    	boolean flag = false;
    	ListNode p = head, q = head;
    	while(q != null && q.next != null){
    		p = p.next;
    		q = q.next.next;
    		if(p == q){
    			flag = true;
    			p = head;
    			break;
    		}
    	}
    	if(flag == false) return null;
    	else{
    		while(p != q){
    			p = p.next;
    			q = q.next;
    		}
    		return q;
    	}
        
    }
}


Test

    public static void main(String[] args){
    	ListNode a = new ListNode(1);
    	a.next = new ListNode(4);
    	a.next.next = new ListNode(3);
    	a.next.next.next = new ListNode(2);
    	ListNode b = a.next.next.next;
    	b.next = a.next;
    	System.out.println(new Solution().detectCycle(a).val);
    }


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值