HelloCoder HelloCoder
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
  • 《可观测和监控》
随笔
关于作者
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
  • 《可观测和监控》
随笔
关于作者
  • 《LearnJavaToFindAJob》

    • 导读

    • 【初级】6~12k档

    • 【中级】12k-26k档

      • JVM进阶

      • Java进阶

      • MySQL

      • 中间件

      • 算法

        • 1-两数之和
        • 高频算法面试题
        • 2两数相加
        • 09-用两个栈实现一个队列
        • 11-盛水最多的容器
        • 19-删除链表的倒数第N个结点
        • 20-有效的括号
        • 22-括号生成
        • 39-组合总和
        • 46-全排列
        • 53-连续最大子序和
        • 64匹马,只有8个赛道,挑选出最快的4匹马
        • 70-爬楼梯
        • 136-只出现一次的数字
        • 141环形链表
        • 206-翻转链表
        • 234回文链表
        • 387-字符串中的第一个唯一字符
        • 543二叉树最大直径
        • 八大排序算法
        • 剪绳子
        • 旋转数
        • 模板
        • 求解立方根不使用库函数
      • 高阶

    • 【高级】26k+档

    • 大厂面试题

    • 求职建议

    • 面经

  • LearnJavaToFindAJob
  • 【中级】12k-26k档
  • 算法
#环形链表
码农阿雨
2022-06-02
目录

141环形链表

# 描述

难度:简单

给定一个链表,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。

如果链表中存在环,则返回 true 。 否则,返回 false 。

示例 1:

输入:head = [3,2,0,-4]
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

进阶:

你能用 O(1)(即,常量)内存解决此问题吗?

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

# 思路

LeetCode的题目描述讲的有点绕,误导了很多人,以上题目是我提取了一些关键消息整理的,如果你还不懂什么意思,可以跟着我的思路一起来看一下。

先上代码,我们常见的链表是这样的:

ListNode listNode = new ListNode(3);
listNode.next = new ListNode(2);
listNode.next.next = new ListNode(0);
listNode.next.next.next = new ListNode(-4);

以上这种链表是没有环形的,只有从链头指向到链尾。

那么假如我们的链表写成这样:

ListNode listNode = new ListNode(3);
listNode.next = new ListNode(2);
listNode.next.next = new ListNode(0);
listNode.next.next.next = new ListNode(-4);
listNode.next.next.next.next = listNode.next; //关键是这里,让节点-4指向节点2

那么现在的链表就有环形了。

题目的意思就是这样,问你这个链表是否有环形。

思路就很简单了,只要判断链表是否有重复的链表节点就行了,实现方法大概就有两种:

  • Hash

    其实你理解了上面就很简单了,把每个节点放进Hash,判断是否有出现过就行了,但是这种空间复杂度最差可能是O(N),因为可能是最后一个节点指向某个前面的节点,这样就要往Hash放N个节点。

  • 双指针

    链表的快慢指针。指定slow指针指向head,quick指向head.nex,然后每次遍历一下(判断条件是show!=quick 就遍历),slow向前走1步,quick向前走2步,如果存在环,quick一定会追上slow;如果没有环,那么quick必然先到达终点(也就是NULL,然后退出遍历)

    **这就像龟兔赛跑一样。**你可以想象一下,乌龟走得慢,兔子走得快,假如它们的赛道是环形的,兔子必然会饶了一圈追上乌龟。

借用一个动图,红色是slow指针,每次只走1步,quick是快指针,每次走两步,如果存在环,它们必然会在某个节点相遇。

# 题解

public class 环形链表141 {
    static class ListNode {
        int val;
        ListNode next;

        ListNode(int x) {
            val = x;
            next = null;
        }
    }

    public static void main(String[] args) {
        ListNode listNode = new ListNode(3);
        listNode.next = new ListNode(2);
        listNode.next.next = new ListNode(0);
        listNode.next.next.next = new ListNode(-4);
        listNode.next.next.next.next = listNode.next;
        System.out.println(hasCycle(listNode));
        System.out.println(hasCycle2(listNode));
    }

    /**
     * 辅助HashSet
     * 时间复杂度:O(N) N是链表的长度
     * 空间复杂度:O(N),主要为哈希表的开销,最坏情况下我们需要将每个节点插入到哈希表中一次。
     *
     * @param head
     * @return
     */
    static boolean hasCycle(ListNode head) {
        Set<ListNode> seen = new HashSet<ListNode>();
        while (head != null) {
            if (!seen.add(head)) {//set如果存在,则返回false
                return true;
            }
            head = head.next;
        }
        return false;
    }

    /**
     * 双指针
     * <p>
     * 时间复杂度:O(N)
     * 空间复杂度:O(1)
     *
     * @param head
     * @return
     */
    static boolean hasCycle2(ListNode head) {
        if (head == null || head.next == null) {
            return false;
        }
        ListNode slow = head;
        ListNode fast = head.next;
        while (slow != fast ) {
            if (fast == null|| fast.next == null) {
                return false;
            }
            slow = slow.next;
            //fast = fast.next  是永远追不上的
            //让fast每次走两步
            fast = fast.next.next;
        }
        return true;
    }
}
阅读全文
×

(为防止恶意爬虫)
扫码或搜索:HelloCoder
发送:290992
即可永久解锁本站全部文章

解锁
#环形链表
上次更新: 2026-03-28 17:00:16
最近更新
01
MySQL支持的锁有哪些
03-28
02
HTTP 是不保存状态的协议, 如何保存用户状态
03-28
03
用户态和内核态的区别
03-28
更多文章>
Theme by Vdoing | Copyright © 2020-2026 码农阿雨
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式