前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
  • 前端算法面试

    • 快速上手——从0到1掌握算法面试需要的数据结构(一)
    • 快速上手——从0到1掌握算法面试需要的数据结构(二)
    • 快速上手——从0到1掌握算法面试需要的数据结构(三)
    • 递归初相见——二叉树递归遍历的三种姿势
    • 算法的衡量——轻松理解时间复杂度与空间复杂度
    • 数组的应用——真题归纳与解读
    • 字符串的应用——真题归纳与解读
    • 链表的应用——真题归纳与解读
    • 快慢指针与多指针——玩转链表复杂操作
    • 姿势特别的链表——环形链表专题
      • 环形链表基本问题——如何判断链表是否成环?
      • 环形链表衍生问题——定位环的起点
      • 快慢指针的思路
      • 弦外之音
    • 栈与队列怎么玩(上)
    • 栈与队列怎么玩(下)
    • 遍历专题 DFS 与 BFS
    • 场景化解读递归与回溯思想在真题中的应用
    • 二叉树真题归纳与解读
    • 特殊的二叉树——二叉搜索树专题
    • 特殊的二叉树——平衡二叉树专题
    • 特殊的二叉树——堆结构及其在排序中的应用
    • 排序算法专题(上)
    • 排序算法专题(下)
    • 普通人也能吃透的动态规划思想专题(上)
    • 普通人也能吃透的动态规划思想专题(下)
完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

环形链表是链表中的一类特殊问题,它和链表反转一样,有着相对恒定的解题思路和适当的变体。如果你对它的特性和解法没有预先的了解和把握,那么前期的推导可能会花去你大量的时间。反过来看,只要我们能够掌握其核心思路,那么不管它怎么变化,大家都能在瞬间找到解题的“抓手”、进而给出正确的解答。

# 环形链表基本问题——如何判断链表是否成环?

真题描述:给定一个链表,判断链表中是否有环。

示例 1:

输入:[3,2,0,4](链表结构如下图) 输出:true

解释:链表中存在一个环

思路解读

其实链表成环的特征非常明显,大家可以结合一个现实中的例子来理解:

假如现实中有一个长跑爱好者李雷,这货很狂,他立了一个 flag,说要徒步环游世界:

地球的周长围出来的这个圆,它就是一个“环”。李雷现在就想围着这个环跑上一圈,说他狂,他也没那么狂——他觉得自己最多跑一圈,为了防止自己跑过界,他决定在出发的地方立一个 flag:

这样,不管李雷走完这个环用了多少年,世事如何变迁,只要他的 flag 还没有倒,那么李雷就一定能回到自己梦开始的地方:)。

换个角度看:只要李雷在闷头前进的过程中,发现了 flag 的存在,那么就意味着,李雷确实走了一个环。毕竟若这是一条线,他将永远无法回到起点。

回到链表的世界里,也是一个道理。一个环形链表的基本修养,是能够让遍历它的游标回到原点

从 flag 出发,只要我能够再回到 flag 处,那么就意味着,我正在遍历一个环形链表。

我们按照这个思路来做题:

编码实现

/**
 * @param {ListNode} head
 * @return {boolean}
 */
// 入参是头结点 
const hasCycle = function(head) {
    // 只要结点存在,那么就继续遍历
    while(head){
        // 如果 flag 已经立过了,那么说明环存在
        if(head.flag){
            return true;
        }else{
            // 如果 flag 没立过,就立一个 flag 再往
            下走
            head.flag = true;
            head = head.next;
        }
    }
    return false;
};
@前端进阶之旅: 代码已经复制到剪贴板

# 环形链表衍生问题——定位环的起点

真题描述:给定一个链表,返回链表开始入环的第一个结点。 如果链表无环,则返回 null。

示例 1:

输入:head = [3,2,0,-4](如下图) 输出:tail connects to node index 1 解释:链表中有一个环,其尾部连接到第二个结点。

示例 2:

  • 输入:head = [1,2](如下图)
  • 输出:tail connects to node index 0

解释:链表中有一个环,其尾部连接到第一个结点。 链表成环2

示例 3:

  • 输入:head = [1](如下图)
  • 输出:no cycle

解释:链表中没有环。

思路解读

这道题在上道题的基础上,仅仅增加了一个“返回链表的成环起点”,其难度定义就从 easy 上升到了 medium。不过对于掌握了关键解题思路的各位来说,这道题仍然是 easy——因为如果一个结点是环形链表成环的起点,那么它一定是第一个被发现 flag 标志已存在的结点:

这一点不难理解,我们试想如果从头开始遍历一个链表,假如途中进入了一个环,那么首先被打上 flag 标签的其实就是环的起点。待我们遍历完这个环时,即便环上所有的结点都已经被立了 flag,但起点处的 flag 一定最先被我们定位到。因此,我们只需要在第一次发现 flag 已存在时,将对应的结点返回即可:

编码实现

/**
 * @param {ListNode} head
 * @return {ListNode}
 */
const detectCycle = function(head) {
    while(head){
        
fe
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
  • 前端算法面试

    • 快速上手——从0到1掌握算法面试需要的数据结构(一)
    • 快速上手——从0到1掌握算法面试需要的数据结构(二)
    • 快速上手——从0到1掌握算法面试需要的数据结构(三)
    • 递归初相见——二叉树递归遍历的三种姿势
    • 算法的衡量——轻松理解时间复杂度与空间复杂度
    • 数组的应用——真题归纳与解读
    • 字符串的应用——真题归纳与解读
    • 链表的应用——真题归纳与解读
    • 快慢指针与多指针——玩转链表复杂操作
    • 姿势特别的链表——环形链表专题
      • 环形链表基本问题——如何判断链表是否成环?
      • 环形链表衍生问题——定位环的起点
      • 快慢指针的思路
      • 弦外之音
    • 栈与队列怎么玩(上)
    • 栈与队列怎么玩(下)
    • 遍历专题 DFS 与 BFS
    • 场景化解读递归与回溯思想在真题中的应用
    • 二叉树真题归纳与解读
    • 特殊的二叉树——二叉搜索树专题
    • 特殊的二叉树——平衡二叉树专题
    • 特殊的二叉树——堆结构及其在排序中的应用
    • 排序算法专题(上)
    • 排序算法专题(下)
    • 普通人也能吃透的动态规划思想专题(上)
    • 普通人也能吃透的动态规划思想专题(下)