力扣:环形链表

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。

说明:不允许修改给定的链表。

进阶:

你是否可以使用 O(1) 空间解决此题?

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:

输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:

输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/linked-list-cycle-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

力扣:环形链表

分析:

f s 记录快慢指针FS的步数 F指针一次走2步 S指针一次1步 f=2s
F S在环内相遇时 f = s+nb b:环的长度,n:F比S多走的圈数,未知,但可以证明是1,即慢指针第一圈必见到快指针
s = nb ,所以 f = 2nb
设 a为头指针走到入环点的步数,步数k为入环后走到(回)入环点的步数 k=a+nb
此时s=nb,所以k= s+a ,S再走a步就可以走到(回)到入环点 而此时从头节点出发走a步也能到入环点(第一次)H.next(a) = S.next(a)
所以此时从head出发的 H指针 经过 a步 将会在入环点和 S指针相遇
通过比较H S指针所在节点是否相等就能得到入环点了
fast快指针节点,一次走二步(跳两节点,.next.next),slow慢指针节点,一次走一步(跳一个节点,.next)

public static ListNode findEnterCircleNode(ListNode head){
    ListNode fast = head, slow = head;
    while (true) {
        //如果当前节点为空或者下一节点为空(说明走到尾结点了),不存在环
        if (fast == null || fast.next == null) return null;
        fast = fast.next.next;
        slow = slow.next;
        if (fast == slow) break;//两指针相遇,记下slow节点(位置)
    }
    fast = head;//head,slow开始同步走,直到在入环点相遇得入环点
    //这里弄个count=0,count++就是求a是几步的过程
    while (slow != fast) {
        slow = slow.next;
        fast = fast.next;
    }
    return fast;

}

 public static void main(String[] args) {
        ListNode node1 = new ListNode(3);
        ListNode node2 = new ListNode(2);
        ListNode node3 = new ListNode(0);
        ListNode node4 = new ListNode(4);

        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node2;

        System.out.println(findEnterCircleNode(node1).val);
}

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) {
        val = x;
        next = null;
    }
}
上一篇:链表有环知多少~


下一篇:2021-10-17 数组