leetcode142_环形链表 II

题目详情

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
在这里插入图片描述

分析

本题是leetcode141. 环形链表的升级问题,可以先通过leetcode141_环形链表这篇博客了解环形链表的基础问题解决方法。

这里假设,已经知道可以通过快慢指针判断链表是否存在循环的情况,如果不清楚为什么使用快慢指针,可以先看一下上面链接的博客。
在这里提出一个有意思的想法,我们在解决问题的时候,有的时候可能需要通过观察推理规律的方法。比如本题目。
我们已经知道一个循环链表,使用快慢指针可以判断出链表存在环,可是我们需要寻找入环点,一开始可能有点懵,这怎么解决啊,别急,让我们看看下图,一看就清楚了。
在这里插入图片描述
如图上推导过程所示,以快慢指针相遇点为开始点同链表起点一起遍历,当两者相等时,就是入环点。
图中的s,f分别为慢,快指针,下标表示第几次的一个状态情况。

注意:有的时候遇到问题,需要通过观察规律并推导一下就能解决,所以可以在草稿上多画画。
详情请看代码。

Java完整代码

/**
 * 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) {
        // head为空,或者head.next为空
        if (head==null || head.next == null || head.next.next == null) {
            return null;
        }
        ListNode s = head.next;
        ListNode f = head.next.next;

        while (s != f) {
            if (f.next == null || f.next.next == null) {
                // 直接返回,为空代表没有环
                return null;
            }
            f = f.next.next;
            // 对于s不用判断,因为f更快
            s = s.next;
        }
        // 出while循环,即为有循环,并且此时的f=s
        ListNode p = head;
        while(p != f) {
            p = p.next;
            f = f.next;
        }
        // 出这个while循环,表示相遇点就是入链表循环的位置
        return p;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值