环形链表 II

题解:hashset(没有达到进阶的要求)

/**
 * 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) {
        Set<ListNode> set = new HashSet<>();
        ListNode node = head;
        while(node!=null){
            if(set.contains(node)) return node;
            else set.add(node);
            node=node.next;
        }
        return null;
    }
}

题解:双指针

一个慢指针l和一个快指针r同时走,慢指针l一次走1步,快指针r一次走2步。当快慢指针相遇时,让另一个指针l0从头出发和慢指针l同时移动且步长都是1,当l0和l相等时就找到了入口节点。
证明思路:https://juejin.im/post/5e64a20ff265da570a5d5633#heading-2

/**
 * 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) return null;
        ListNode l=head,r=head,l0=head;
        while(true){
            l=l.next;
            r=r.next==null? null:r.next.next;
            if(l==r&&l!=null){
                while(l!=l0){
                    l=l.next;
                    l0=l0.next;
                }
                return l;
            }
            if(r==null){
                return null;
            }
        }

    }
}

参考剑值offer代码

分为两部分:
1、先计算出环内节点数目n
2、快指针先走n步,之后慢指针和快指针同时走。当它们相遇就是入口

/**
 * 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) {
        ListNode h = head;
        int goFirst = numCycle(head);
        if(goFirst == 0) return null;
        ListNode pFast = head,pSlow = head;
        //快指针先走环内节点指针数
        for(int i=0;i<goFirst;i++){
            pFast = pFast == null? null : pFast.next;
        }
       // int index = 0;
        while(pFast != pSlow){
            pSlow = pSlow == null? null:pSlow.next;
            pFast = pFast == null? null:pFast.next;
        }
        return pFast;

        
    }

    //判断环内节点数目
    public int numCycle(ListNode head){
        ListNode pSlow = head,pFast = head;
        while(pFast != null){
            pSlow = pSlow == null ? null : pSlow.next;
            pFast = pFast.next == null ? null : pFast.next.next;
            if(pFast == pSlow) break;
        }
        if(pFast == null) return 0;//无环
        ListNode pFastNext = pFast.next;
        int cnt = 1;
        while(pFast != pFastNext){
            cnt++;
            pFastNext = pFastNext.next;
        }
        return cnt;
    }
}

posted @   浅滩浅  阅读(183)  评论(0编辑  收藏  举报
编辑推荐:
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
阅读排行:
· 从零开始开发一个 MCP Server!
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Ai满嘴顺口溜,想考研?浪费我几个小时
· Browser-use 详细介绍&使用文档
历史上的今天:
2019-07-18 华为2019秋招笔试真题
点击右上角即可分享
微信分享提示