LeetCode:Linked List Cycle II 链表回环入口处

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

To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

Note: Do not modify the linked list.
Example 1:
Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
Explanation: There is a cycle in the linked list, where tail connects to the second node.
Example 2:
Input: head = [1,2], pos = 0
Output: tail connects to node index 0
Explanation: There is a cycle in the linked list, where tail connects to the first node.
Example 3:
Input: head = [1], pos = -1
Output: no cycle
Explanation: There is no cycle in the linked list
Follow up:
Can you solve it without using extra space?
代码:
在这里插入图片描述
1、单链表有环,那么进入环内的指针只能在环内移动;
2、如果指针p1每次走一步,而p2每次走两步,那么p1和p2一定会在环内相遇,以此判断有环;物理题:两人速度相差为1,绕圈跑。
3、而且p2不需要再跑完一圈就能追上p1,因为p1到达入口时,p2与p1距离不足一圈,只要再跑距离差就能追上。
4、那如何判断环的入点?p2的速度是p1速度的两倍,当p1和p2相遇时,p2比p1多跑一倍距离。也就是说p2跑了2(s+r)=s+r+n*(r+l)距离(C为相遇点,n为跑的圈数),显然n=1,s=l,n>1时走s的距离相当于在圈内跑n-1圈+l的距离,刚好又到入口点s=(n-1)(r+l) + l

/**
 * 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;

        ListNode firstp = head;
        ListNode secondp = head;
        boolean isCycle = false;

//         遍历链表知道
        while(secondp != null) {
//             走一步
            firstp = firstp.next;
//             如果secondP走到底那就说明没环
            if (secondp.next == null) return null;
//             走两步
            secondp = secondp.next.next;
            if (firstp == secondp) { isCycle = true; break; }
        }

        if(!isCycle) return null;
        firstp = head;
        while( firstp != secondp) {
            firstp = firstp.next;
            secondp = secondp.next;
        }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值