哈希表、滑动窗口、二叉树:力扣刷题思路与边界复盘
2026年1月21日今天的力扣刷题我选了三个方向哈希表、滑动窗口、二叉树。安排这个组合不是随手点题而是有意为之。刷题这件事很多人从一开始就理解偏了以为做得多、做得快就是厉害其实真正的门槛在于能不能稳定地想清楚解法边界并且把一类题吃透。如果你正处在刷题瓶颈期或者准备技术面试这篇文章值得看完。我会把今天每道题的完整思路、代码写法、边界测试和踩坑记录都摊开来讲最后再分享一套我自己验证过三个月的复盘方法。1. 题单设计为什么要把三种不同题型放同一天刷1.1 三题三型式的组合逻辑连续刷同一类题会制造一种假象叫“手感”。我在早期刷题时踩过这个坑连续五天只刷数组相关的题到第六天换成一个链表题脑子像突然断电一样连头节点为空这种最基本的情况都想不起来。后来我给自己定了一个规则每天至少轮换三种互不相同的核心题型。今天的组合是哈希表、滑动窗口和二叉树。这三个方向没有一个是靠死记硬背能混过去的。哈希表考察的是“空间换时间”的思考方式能不能把查找从线性变成常数时间。滑动窗口本质是暴力枚举的优化关键在边界控制一旦 windows 的左右指针没写对整个算法就崩了。二叉树相关题是递归思维的主战场同时又能延伸出迭代写法是训练“递归转栈”的最佳材料。把它们放在同一天刷还有一个好处三种解法彼此参照。哈希表用额外空间换速度滑动窗口用双指针把复杂度压回线性二叉树递归则反过来把问题交还给树的结构本身。练一题时总会想起另外两题的思路这种交叉记忆比单题反复刷要牢得多。1.2 当天的完成情况一览我习惯在开始前把当天题单的难度和预计耗时列出来不是为了完成任务式打卡而是用来校准自己的节奏。序号核心题型预计用时实际用时完成情况第1题哈希表15分钟约20分钟AC并对边界做了扩展测试第2题滑动窗口30分钟约35分钟AC复刷一遍官方优化思路第3题二叉树深度15分钟约18分钟递归与迭代两种写法均通过这里我想强调一下“实际用时长一点不是坏事”。很多人刷题的焦虑来自别人十分钟 AC自己搞了半小时其实完全没必要。如果每次都能在不会的时候停下来问一句“我卡在哪”半小时的卡顿是有价值的。我今天的第2题多花五分钟原因是写错了一个if和while这个错误我后面专门复盘了它非常典型。2. 第一题两数之和从暴力到哈希的完整推导2.1 题目回顾与暴力解法题目非常经典给定一个整数数组nums和一个目标值target返回两个下标使得这两个下标对应数字之和等于target。假设每种输入只对应一个答案且同一个元素不能使用两次。暴力解法不需要动脑直接双重循环def two_sum(nums, target): n len(nums) for i in range(n): for j in range(i 1, n): if nums[i] nums[j] target: return [i, j] return []这段代码的时间复杂度是 O(n²)空间复杂度是 O(1)。拿宴会凑桌打个比方就像有一屋子人你要找出两个人正好凑成 100 斤最笨的办法是把每一对组合都称一遍。人少无所谓人一多组合数量会爆炸增长。这种思路能通过小规模测试但数据量一旦上去就会被卡超时。写暴力解看起来多余但我一直建议先把它写出来。原因有两个第一它保证了你对题目的理解没有偏差第二它给出了一个正确的基线后续优化时可以反复对照确认结果没有变。很多新手一上来就瞄着最优解写结果边界条件全错反而不如先暴力后优化来得稳。2.2 一次遍历的哈希表解法优化的核心问题是能不能在遍历到某一个数字时立刻知道它要找的“另一半”之前出现过这需要把已经看过的数字存下来并且能快速查找。数组不行因为它的下标是数字的物理位置和人名对不上号。哈希表正好合适它的 key 存数字本身value 存数字对应的下标。这样每遍历一个数字num只查一下target - num在不在表里。如果在直接返回两个下标如果不在就把当前数字登记进表。def two_sum(nums, target): num_to_index {} for i, num in enumerate(nums): need target - num if need in num_to_index: return [num_to_index[need], i] num_to_index[num] i return []这里有个容易被忽略的顺序问题必须先查“另一半”有没有出现过再把自己登记进去。如果先把自己存进哈希表再回头查target - num那么当num * 2 target时就会查到自己等于把同一个元素用了两次。这道题里的“不能使用同一个元素”指的就是这个约束。复杂度上时间变成 O(n)空间变成 O(n)。拿刚才的宴会类比来说相当于你在大厅里放了一块登记板每进来一个人就先问“我要找的人在板上吗”不在就写上名字。整个过程只需走过一遍人群速度和正确性都提升了。2.3 这道题我翻过的三个细节我在不同阶段刷过这道题三遍每次都有新教训。第一个教训是哈希表选的容器类型要和返回值对齐。如果你只想判断存不存在用集合set没问题但这道题要求返回下标集合只会告诉你数字存在拿不到位置信息。刷题时先看清楚返回类型再决定用set还是dict可以少走很多弯路。第二个教训是不要自己预设输入全是正数。有的题解为了简化会默认nums里都是正数可在真实的测试用例里负数、零、重复数字全都有。一旦输入包含 -1 和 target 是负数很多默认逻辑就会失灵。所以我在写代码前会刻意在注释里写一句“输入包含负数和重复值吗”帮自己提前防范。第三个教训比较隐蔽题目说“只有唯一答案”不代表你可以随便乱返回。边遍历边存储的解法天然保证返回的两个下标前者是已经在哈希表里的后者是刚遍历到的顺序必然是小的在前。如果先构建完整哈希表再查一遍反而需要注意顺序问题。工程上推荐用一次遍历的版本简单还不容易错。3. 第二题无重复字符的最长子串滑动窗口的 while 别写成 if3.1 窗口想法的来源题目本身很短给定一个字符串找出其中不含重复字符的最长子串的长度。比如abcabcbb答案是 3因为最长的不含重复字符的子串是abc再往后走一个a就会冲突。暴力做法是枚举所有可能子串检查里面有没有重复字符。这是 O(n²) 甚至 O(n³)完全不可取。但注意一个现象如果从位置i开始的最长合法子串已经走到了位置j那么下一步只需要把左边界向右移动保持窗口内不重复再继续向右扩展。这就是滑动窗口。生活里的类比很简单你在一卷长纸条上用剪刀划出一个固定宽度的区间一边是左指针一边是右指针。右指针一直往前扩左指针只在窗口内部“违规”时才往回收。这样整个字符串只需要遍历一次问题就从枚举所有子串变成了维护一个动态区间。3.2 代码实现与逐行解释用集合记录当前窗口内出现过的字符核心代码如下def length_of_longest_substring(s): window set() left 0 ans 0 for right, ch in enumerate(s): while ch in window: window.remove(s[left]) left 1 window.add(ch) ans max(ans, right - left 1) return ans逐行拆解一下。left是左指针初始为 0right是右指针随着 for 循环自动前进。循环变量ch是当前右指针指向的新字符。接下来的while ch in window是整个算法的灵魂只要新字符已经出现在窗口里就不断删掉s[left]并且把left右移。举个例子字符串pwwkew走到右指针指向第二个w时窗口是{p, w}。while会先删掉pleft 变 1窗口变成{w}但此时w仍然在窗口里所以继续删掉s[1]也就是第一个wleft 变 2窗口清空。之后才能把第二个w放进去。这段逻辑的最关键区别就在while而不是if。如果写成if ch in window遇到连续重复时会只删除一次窗口内部仍然残留重复字符。前面的例子中if版本删掉p之后就直接往下走第二个w还在集合里窗口里的字符集合与实际区间对不上后续计算的长度全是错的。我当天写错就是栽在这个问题上。3.3 边界测试用例与复杂度校准写完主逻辑后我一般会先跑四个边界用例而不是直接拿官方用例测。第一个是空字符串。此时 for 循环一次都不执行窗口为空答案是 0符合预期。第二个是单字符a。right 从 0 开始窗口加入a答案是0 - 0 1 1正确。第三个是全重复字符串aaaa。每一步都会触发while窗口清空再放入一个字符ans 永远是 1。如果if版本跑这里会得到错误长度。第四个是完全不重复的abcde。窗口始终不需要收缩左指针不动ans 会随右指针一直增长到 5。跑完这四个边界基本可以确认算法对窗口收缩逻辑没有大问题。时间复杂度是 O(n)每个字符最多被右指针读一次、左指针删一次实际是线性量级。空间复杂度 O(min(m, n))m 是字符集大小n 是字符串长度对 ASCII 字符来说可以看成 O(1)。我顺便提一个进阶方向当前是 O(n)但 left 指针有时会被while一次次地推着走整体仍然是线性的。更激进的优化是用哈希表记录每个字符最后一次出现的下标遇到重复时让 left 直接跳到那个重复字符的下一个位置。这种跳跃版写法更短但第一次接触滑动窗口时不建议直接学跳跃版因为while版更容易让人理解窗口移动的物理过程。4. 第三题二叉树最大深度递归和迭代我都要会写4.1 递归的天然写法与思维解释二叉树的最大深度指从根节点到最远叶子节点的最长路径上的节点数。这道题考察的是对树这种递归结构的理解所以递归版本几乎是“天性”写法。def max_depth(root): if not root: return 0 return 1 max(max_depth(root.left), max_depth(root.right))它的思考方式非常直白一棵树的高度等于左子树高度和右子树高度的较大值再加 1。如果节点是空说明这棵子树的高度是 0。这就好比你要知道一棵树有多高只需要分别量一下左侧枝条和右侧枝条谁更高再在较高的那边加上树的根部这一段。第一次写递归容易卡在一个点上为什么max里面可以直接写两个递归调用原因在于递归函数把“当前节点的问题”拆分成了“子节点的问题”自己调用自己时没有改变问题的性质只是让问题的规模在变小。每次递归都在向叶子方向前进空节点就是终止条件。只要终止条件写对递归就不会无限跑下去。4.2 层序迭代怎么把递归翻译成循环递归写起来漂亮但有一个现实问题如果二叉树退化成一个很深的链比如 10 万层递归深度会超过运行时栈的承受能力直接栈溢出。所以在实际工程里我也要求自己必须会写迭代版。我最常用的迭代姿势是层序遍历也就是 BFS。一层一层地把节点扫过去扫完一层就让高度加一。from collections import deque def max_depth_iter(root): if not root: return 0 q deque([root]) depth 0 while q: for _ in range(len(q)): node q.popleft() if node.left: q.append(node.left) if node.right: q.append(node.right) depth 1 return depth这段代码里最值得研究的是for _ in range(len(q))。因为循环体内部会向队列里加入下一层节点如果直接写成while q:然后在循环里同时弹出和加入就会把当前层和下一层混在一起。用range(len(q))先固定当前层的节点数量循环里只弹出当前层的节点下一层刚加进来的节点不会被这一轮触碰。每轮循环结束队列里的全是下一层节点这时才把 depth 加一。我建议把这两段代码摆在一起对比着看。递归版是深度优先的思路迭代版是广度优先的思路它们都能求出正确深度但在树结构上走的路线完全不同。理解了这个对照很多看似复杂的层序遍历题都会变得清晰。4.3 从一题连出三题平衡树、直径、最大深度刷题不能只满足于过一道题。每次刷完我会问自己一个问题这道题稍微改一下我还能不能写出来最大深度这道题稍微改一改就能变成另外两个高频题。第一个是“判断平衡二叉树”。思路是对每个节点左子树深度和右子树深度差不超过 1。你只需要在递归返回深度的同时检查一下差值是否超过 1。表面上是个新题内核还是最大深度。第二个是“二叉树直径”。直径是任意两个节点之间路径上最多的边数。直径不一定经过根节点但它一定等于某个节点的左子树深度加上右子树深度。这个值在求最大深度的递归过程中顺带更新一下就能求出。第三个是“二叉树最小深度”。看起来是把 max 改成 min但有一个坑如果某个节点只有左孩子没有右孩子那么它的右子深度概念上不等于 0因为最小深度只计算根到最近的叶子节点路径。直接套 min 会得到错误结果。刷完最大深度后立刻做最小深度题能暴露出很多对“空节点”的概念误解。5. 复盘总结刷题最常踩的坑和我的调整策略5.1 边界条件漏掉是新手和老手都会犯的错我给自己建立了一个底线任何题写完主逻辑之后不马上提交先写三个测试用例。这三个用例的顺序固定第一是空输入用例第二是只有一个元素或单节点的用例第三是极端重复用例。对应到今天的题就是空字符串、单字符、全重复字符对应到二叉树题就是根节点为空、只有左子树、只有一个节点。边界条件为什么总是漏核心原因是人脑在处理“正常情况”时更顺手对“什么都没有”和“只有一个”的直觉很弱。比如链表题忘记处理头节点为 null树题忘记处理空节点字符串题没考虑全重复。这些错误不是知识问题而是流程问题。把“写三个边界用例”固化成习惯比记住一百条细节更管用。5.2 只刷不总结等于白刷我认识一位在技术群里一起刷题的朋友他三个月刷了两百题看起来量很大但一写现场代码就卡住。后来我跟他聊了一次发现他的做题流程是看题想不出来马上翻答案看懂下一道。刷得很快但每道题都没有真正形成自己的思路更别说把解法细节记在脑子里了。我自己采用的是一题三写法。第一遍不看任何题解能写成什么样就写成什么样哪怕超时也必须留下一个“自己的版本”。第二遍在看题解或者官方精讲之后关上答案自己重新写一遍。第三遍隔天早晨起床先默写一遍。整个过程看起来慢实际效果非常好因为第三遍默写是在检验长期记忆而不是短期记忆。如果你觉得三遍太累可以退一步至少做到“隔天重写一遍”。只刷不总结刷一百题也很难在面试里稳定输出。5.3 做题卡壳多久该看答案我见过两种极端。一种人是十分钟没思路就开始崩溃直接翻题解另一种人死磕两小时明明已经卡在同一个点上很久了就是不肯看答案。前者失去了独立思考和挣扎的机会后者时间成本太高一天下来做不了几道题。我的时间分配规则是简单题十五分钟没有完整思路记录卡点之后看思路提示中等题三十分钟没有思路看思路提示然后自己写代码如果六十分钟仍然写不出完整正确解才允许从头到尾看题解但必须做一件事把题解关掉在两小时内重写一遍当天晚上再写一遍。这样做的好处是看答案前你已经带着问题去看了理解深度完全不同。很多时候你不是不会而是还没把问题拆清楚就被焦虑推去看答案看完也只记得套路不懂来龙去脉。5.4 让每道题都留下可追溯痕迹最后分享一个小习惯。我每刷完一道题会在本地维护一个简单的刷题日志记录四件事题目关键词、我采用的解法、犯过的错、一句话解法思路。不需要工具一个纯文本文件就够了。这个日志的作用不是每次刷题前翻一遍而是每周固定挑一天把过去三天做错的题再写一遍。日志里那句话“一句话解法思路”尤其关键。比如“两数之和边遍历边查另一半查完再登记”看似简单但这句话能帮你在一周后快速唤醒完整思路。我试过直接把官方题解抄进去发现没什么用只有用自己的话压缩过的思路隔几天还能被顺利调取。三个月坚持下来我最大的感受是力扣刷题最终拼的其实不是智商而是你能不能建立一个“遇到问题—建立模型—选择解法—验证边界—复盘记录”的循环。只要这个循环是稳定的题量和正确率都会慢慢涨上来。希望这份刷题记录能给你提供一条可以复制的路径。

相关新闻

HOL4列表与集合证明实战:操作系统形式化验证的基础打法

HOL4列表与集合证明实战:操作系统形式化验证的基础打法

两年前我第一次接触操作系统形式化验证时,导师递给我一个任务:验证一个迷你调度器的就绪队列性质。我当时的反应和大多数人一样——队列不就是个列表嘛,往里塞任务再取出来,这个有什么好证的?结果真上手才发现&#xf…

2026/10/14 3:51:40 阅读更多 →
Captura录屏+ffmpeg压缩实战:从录制到上传的完整链路

Captura录屏+ffmpeg压缩实战:从录制到上传的完整链路

简介:这份资源是 Captura 录屏工具与 ffmpeg 的整合包,面向需要轻量级屏幕录制、教学演示或游戏录制的用户,尤其适合希望免安装、开箱即用的 Windows 使用者。压缩包共 91 个文件,约 22.16MB,以 37 个 dll 动态库、34 …

2026/10/14 3:51:40 阅读更多 →
P2P风险评级中的机器学习算法落地全流程

P2P风险评级中的机器学习算法落地全流程

简介:这是一篇《机器学习算法在P2P网贷平台风险评级中的应用》的学术论文PDF,面向金融科技研究者、互联网金融从业者及机器学习爱好者,系统阐述如何利用机器学习模型对P2P平台及其借款人进行风险评级。论文刊于《时代金融》2017年&#xff0c…

2026/10/14 3:50:40 阅读更多 →

最新新闻

Qt Linux打包失败原因与linuxdeployqt避坑指南

Qt Linux打包失败原因与linuxdeployqt避坑指南

简介:本资源是一份面向Linux Qt开发者的技术实践指南,聚焦Ubuntu环境下使用linuxdeployqt工具完成Qt程序跨机部署的核心痛点。针对无Qt运行环境的目标机器,系统性梳理了从Qt开发环境配置、linuxdeployqt源码编译(含Ubuntu 18.04兼…

2026/10/14 4:46:57 阅读更多 →
开放权重模型:可控部署、商用微调与硬件感知推理实战

开放权重模型:可控部署、商用微调与硬件感知推理实战

1. 项目概述:一场被公开谈论的“开放权重”战略卡位战最近刷到一条消息,说英伟达正在和一家叫 Reflection AI 的初创公司洽谈收购或追加投资——这事本身不稀奇,大厂盯上潜力股是常态。但真正让我多看了两眼的,是它背后那个反复出…

2026/10/14 4:46:57 阅读更多 →
Linux系统工具pstack二进制瘦身实战:ELF优化与C语言编译精简

Linux系统工具pstack二进制瘦身实战:ELF优化与C语言编译精简

1. 一个被低估的系统工具&#xff1a;pstack 的“瘦身”为什么值得较真很多人第一次听说 pstack&#xff0c;是在某个进程卡死、CPU 疯狂打满、日志毫无输出的深夜。运维同事甩来一句&#xff1a;“快&#xff0c;pstack 看下堆栈&#xff01;”——于是你敲下pstack <pid&g…

2026/10/14 4:46:57 阅读更多 →
PS5数据管理方案:AnyPS5搞定存档备份与远程串流

PS5数据管理方案:AnyPS5搞定存档备份与远程串流

1. 为什么需要AnyPS5方案PS5入手之后&#xff0c;很多玩家都会遇到同一个问题&#xff1a;主机硬盘看着不小&#xff0c;真用起来却总是捉襟见肘。一款大型游戏动辄上百GB&#xff0c;加上截图、录像、存档备份&#xff0c;内置SSD没过多久就亮红灯。更麻烦的是&#xff0c;一旦…

2026/10/14 4:46:57 阅读更多 →
实时事件分析系统架构设计与Flink+Kafka+ClickHouse实战

实时事件分析系统架构设计与Flink+Kafka+ClickHouse实战

1. 从“rea”这个标题说起&#xff1a;一个被低估的缩写背后藏着什么第一次看到“rea”这个标题的时候&#xff0c;我脑子里蹦出来的第一反应是——这大概率又是一个被缩写玩坏的项目名。做技术的人都有个通病&#xff0c;喜欢把长名字砍成三四个字母&#xff0c;仿佛名字越短越…

2026/10/14 4:46:57 阅读更多 →
一文搞懂MySQL socket连接:原理、配置与2002/2003故障排查

一文搞懂MySQL socket连接:原理、配置与2002/2003故障排查

一次线上事故让我把socket连接这件事彻底搞明白了。当时某个项目组反馈所有本地应用突然连不上MySQL&#xff0c;我登录服务器一看&#xff0c;mysqld进程明明活着&#xff0c;3306端口也在正常监听&#xff0c;可本地应用全部报socket错误。查了半个多小时&#xff0c;最后发现…

2026/10/14 4:45:56 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起&#xff1a;它到底想解决什么问题第一次看到"AnyPS5"这个标题&#xff0c;我脑子里冒出来的第一个念头是&#xff1a;这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述&#xff1a;Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师&#xff0c;我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性&#xff0c;实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景&#xff0c;也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间&#xff0c;确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中&#xff0c;这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介&#xff1a;基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码&#xff0c;面向计算机相关专业课程设计与期末大作业学生&#xff0c;以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程&#xff0c;…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程&#xff1a;键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化&#xff0c;十个新手有八个栽在"往输入框里填东西"这件事上&#xff1a;要么填不进去&#xff0c;要么填了一半&#xff0c;要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程&#xff1a;阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀&#xff1a;什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面&#xff0c;跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →