算法笔试经典题:为什么全相等的最优解是中位数?
先交代一下背景2026年春招笔试里算法岗这套卷子的第一题叫“全相等”题目本身不难但它出现在卷首承担的任务很特殊——把心态稳住、把基础盘接住。我陪人复盘时发现不少同学在五分钟内能写出能过的代码可被追问“为什么中位数是最优解”时反而卡住。这题真正值得写的不是代码本身而是背后的推导链路和那些容易被忽略的边界细节。这篇文章把题面、推导、三种语言实现、在线验证方法和几个高频变形一起讲透给准备笔试的同学做一份可直接复用的笔记。1. 这道“全相等”在春招笔试中的定位与考察意图1.1 第一题通常承担的角色算法岗笔试普遍是2到4道题时间两小时上下。第一题大概率是“签到题”但也因为这样很多人反而栽跟头——要么读题太快漏掉操作限制要么觉得简单就不写测试用例直接提交后才发现溢出或边界错误。全相等这题在套路结构上非常标准数组、操作、最小代价三个要素齐全但没有任何复杂数据结构排序加一行统计就能解决。它本质上是考察“能不能识别出绝对值和最小化的本质”。我自己的经验是不要把签到题当“送分题”对待要当“热身题”和“心态题”。写题速度固然重要但第一题如果栽了后面的状态会受很大影响。这套卷把全相等放第一题明显就是想让多数人先拿稳一血把节奏带起来。1.2 考官到底想看什么一道全相等对应了三个能力点。第一是建模能力能否把“操作次数最少”抽象成“选一个目标值让所有数到它的绝对距离总和最小”第二是算法设计能力能否从枚举优化到排序后取中位数并能给出复杂度分析第三是基础功三种语言里能不能写出无溢出、边界正确的代码特别是当数组元素范围拉到很大时。这些能力都不是靠背题能练出来的。我见过不少人的准备方式是刷题量堆上去但问到“为什么绝对值距离和的最优解是中位数而不是平均数”时只能说“这题都是这么做的”。这种回答在笔试环节没事到了面试撕题环节基本会被立刻追问到底。把原理吃透才是这题真正的价值所在。2. 整理后的题面、数据范围与三组自测样例2.1 题面与输入输出约定题目回忆版整理如下给定一个长度为 n 的整数数组 a每次操作可以选中一个下标 i让 a[i] 加 1 或减 1。求最少需要多少次操作才能让数组中所有元素的值相等。输入格式 第一行一个整数 n表示数组长度。第二行 n 个整数表示数组元素。输出格式 一行一个整数表示最小操作次数。数据范围 n 最大到 10^5a[i] 可以为负数绝对值不超过 10^9。看到这个数据范围第一反应就是答案可能超过 int 范围。n 是 10^5每个数幅度 10^9最坏情况答案量级在 10^14 左右long/long long 起步。Java 用 longC 用 long longPython 不需要考虑整数天然够用。2.2 三组测试样例我在考场复盘时习惯构造几组“带心机”的样例而不是只用题目给的示例跑一遍。这三组是验证时最常用的输入期望输出说明5 / 1 2 3 4 56奇数长度目标取中位数 34 / 1 1 100 100198偶数长度目标可取区间内任意值1 / 420单元素边界情况第一组是最经典的示例目标取 3代价为 210126。第二组有意思得多数组按序排好后是 1、1、100、100中位数区间是 [1, 100]目标不管取 1、100 还是 50代价都是 198。这正好引出一个容易被忽略的结论偶数长度时目标只要落在中间两个数之间代价相同。第三组是边界情况n1 时答案必然是 0排序后 target 取唯一元素即可。2.3 样例里的“小心机”第二组样例是区分“背模板”和“理解原理”的好工具。如果只记住“排序后取 a[n/2]”输出 198这没错但如果被问“取 a[n/2-1] 行不行”也能输出 198这就说明你真正懂了。实际写代码时偶数组取 a[n/2] 或 a[n/2-1] 都正确代价相同。没有哪个更好只是习惯问题。C 里 sort 后下标从 0 开始n/2 是上中位数Java 和 Python 同理。这个细节在笔试里不会造成错误但在面试中能体现边界考虑是否周全。这类小心机在真实题目里不少见尤其第一题出题人会故意放一个不疼不痒的迷惑点看你能不能识别出来。全相等的迷惑点就是平均数很多人下意识觉得“让所有数相等那不就是变成平均值吗”而正确答案偏偏是中位数。这个反直觉点下一节详细展开。3. 从暴力枚举到排序中位数的三步推导3.1 暴力枚举的复杂度瓶颈最直接的思路枚举所有可能的目标值 x对每个 x 计算 sum(|a[i]-x|)取最小值。这个思路完全正确但复杂度是 O(n × range)其中 range 是 a[i] 的范围。数据范围里 a[i] 绝对值到 10^9range 接近 2×10^9n 是 10^5运算量达到 2×10^14 量级。这个规模在笔试环境下显然跑不完。不过暴力枚举在“对拍验证”阶段非常有用我后面会专门讲怎么用暴力程序和小数据量随机数组互相验证确保高效写法没有写错。笔试里这种思路的价值不在于拿满分而在于作为参照物。3.2 凸函数视角三分搜值可行但不优雅稍微观察一下 f(x) sum(|a[i]-x|)绝对值函数是凸函数非负加权求和仍然是凸函数。凸函数在区间上一定存在唯一的最小值点或者一段平坦区间所以可以用三分搜索在 [min(a), max(a)] 范围内找最优目标值。三分法的复杂度是 O(n log range)也就是 10^5 × 31 次左右的绝对值计算完全能过。但这个方法有个问题实现起来比排序取中位数复杂精度和边界处理也容易出 bug。整数三分需要仔细处理区间收缩条件稍不注意就会死循环或漏掉端点。笔试第一题的原则是“用最稳的方法拿最快的分”三分法虽然正确但不够优雅。3.3 排序后的配对思考真正的关键一步是把数组排序然后成对观察。排序后 a[0] 最小a[n-1] 最大。考虑这两个点到目标 x 的绝对距离之和当 x 落在 [a[0], a[n-1]] 区间内时|a[0]-x| |a[n-1]-x| 恒等于 a[n-1]-a[0]也就是区间长度。当 x 落在这个区间外时这个和会变大。这给了我们一个“剥洋葱”的思路最优目标一定在最值区间内部否则第一项会白损失。剥掉最外层一对后剩下的数组 [a[1], a[n-2]] 又变成了同样的子问题。不断向内剥直到剩一个点或两个点。n 为奇数最后剩下中间那个点它就是排序后的中位数也是最优目标值。n 为偶数最后剩下中间两个点最优目标可以是它们之间的任意值代价相同。这个配对思路的价值在于它不需要任何高等数学工具画一条数轴就能跟面试官讲清楚。从暴力到三分的进步是算法层面的优化从三分到排序取中位数的进步则是模型识别层面的优化——识别出了这个问题的本质结构。这也是为什么这题被放在第一题它考察的正是从“能算”到“会算”的思维跳跃能力。4. 中位数最优性的严格证明与常见误区4.1 配对夹逼的完整证明为了让结论更有说服力我把上面的配对思路写成更严格的形式。假设排序后的数组为 b[0] ≤ b[1] ≤ ... ≤ b[n-1]目标为 x。先把整个数组的和式写成配对形式sum(|b[i]-x|) (|b[0]-x| |b[n-1]-x|) (|b[1]-x| |b[n-2]-x|) ...对任意一对 (b[i], b[j])其中 ij有不等式|x-b[i]| |x-b[j]| ≥ b[j] - b[i]当且仅当 x 位于 [b[i], b[j]] 时取等号。于是总代价有下界sum(|b[i]-x|) ≥ (b[n-1]-b[0]) (b[n-2]-b[1]) ...如果 x 能同时落在每一对的内侧下界就能达到。这个“同时落在每一对内侧”的条件最终要求 x 落在最内层的区间内n 为奇数时最内层是一个点 b[n/2]x 必须等于它这就是中位数。n 为偶数时最内层是区间 [b[n/2-1], b[n/2]]x 取区间内任意值都能达到下界。所以中位数的正确性不是一个经验结论而是严格推导出来的。这段证明在面试中讲出来会明显区别于“背答案”的候选人。4.2 均值不是最优一个反例平均数误区是这个题最经典的陷阱。很多人觉得“全相等当然是把所有数变成平均值”但平均值只有在误差平方和最小化时才是最优。这题用的是绝对值距离绝对值对应的最优中心是中位数。举一个直接反例数组 [1, 2, 100]。平均值约 34.33中位数是 2。如果目标是 2代价是 |1-2| |2-2| |100-2| 1 0 98 99。如果目标是 34代价是 33 32 66 131目标是 33代价是 32 31 67 130。不管怎么取均值附近的整数代价都远大于取中位数的代价。深层原因是均值对极端值极其敏感而绝对值距离函数的增长是线性的中位数对离群点有很强的鲁棒性。换到实际场景理解一次极端操作的成本与距离成正比而不是与距离的平方成正比所以不做任何“惩罚放大”首选目标自然跟着中间位置走而不是被极端值拽走。这个反例也建议笔试前多拿几组随机数据验证巩固直觉。5. Java/C/Python三版实现与边界细节5.1 Java实现import java.util.Arrays; import java.util.Scanner;public class Main { public static void main(String[] args) { Scanner sc new Scanner(System.in); int n sc.nextInt(); long[] a new long[n]; for (int i 0; i n; i) { a[i] sc.nextLong(); } Arrays.sort(a); long target a[n / 2]; long ans 0; for (long x : a) { ans Math.abs(x - target); } System.out.println(ans); } }Java 里最值得注意的就是数据类型。a[i] 范围到 10^9用 int 存没问题但累加距离时 ans 的最大值是 n × range也就是 10^5 × 2×10^9 2×10^14远超 int。直接把数组声明成 long[]既避开了求和溢出也省了后续类型转换的麻烦。读取方面笔试环境一般给标准输入用 Scanner 足够。如果追求更快的输入可以用 BufferedReader 手写解析但对于 10^5 规模的数据Scanner 完全够用没必要增加复杂度。5.2 C实现#include bits/stdc.h using namespace std;int main() { ios::sync_with_stdio(false); cin.tie(nullptr);int n; cin n; vectorlong long a(n); for (int i 0; i n; i) { cin a[i]; } sort(a.begin(), a.end()); long long target a[n / 2]; long long ans 0; for (long long x : a) { ans llabs(x - target); } cout ans \n; return 0;}C 版要提两个细节。第一个是 ios::sync_with_stdio(false) 和 cin.tie(nullptr)这几乎是竞赛代码的标配能显著加快标准输入输出。第二个是绝对值函数如果 x 和 target 都是 long longabs 在某些编译环境下返回的是 int会被截断造成错误稳妥起见直接用 llabs。有些人会写ans abs(x - target)在数据范围小的时候没问题但遇到 10^9 级别的差值就不安全了。统一用 llabs或者干脆每次都转成 long long 再算能避免所有隐患。还有一个边界点是 n 为 1 时vector 里只有一个元素a[n/2] 就是 a[0]循环求和为 0正确输出不需要额外特判。5.3 Python实现import sysdef main(): data sys.stdin.read().split() if not data: return n int(data[0]) a list(map(int, data[1:1 n])) a.sort() target a[n // 2] ans sum(abs(x - target) for x in a) print(ans)ifname main: main()Python 版最需要注意输入解析。笔试中行尾可能有多余空格甚至整个输入横跨多行用 sys.stdin.read().split() 统一分割后转 int是最稳妥的读取方式。如果只用 input().split()遇到空白行或数据折行时会比较被动。target a[n // 2]对奇数长度取正中对偶数长度取上中位数代价正确。Python 的整数没有溢出概念sum 累加多少位都能存下这也是 Python 写算法题的一个省心点。性能上10^5 规模的排序和求和都在毫秒级没有任何压力。5.4 复杂度与常见坑三份代码的时间复杂度完全一致排序 O(n log n)求和 O(n)总复杂度 O(n log n)空间复杂度 O(1)不考虑输入数组本身的存储。这个复杂度在 10^5 的数据量下非常安全。常见坑集中在这几个地方坑点后果规避方式答案用 int 累加溢出变成负数用 long/long longC 用 abs 处理 long long可能截断用 llabs偶数长度取中位数疑惑心态波动理解区间等价性Python 读取只用 input().split()多行数据出错用 sys.stdin.read().split()我个人推荐的做法无论题目数据范围多“温柔”一律按最坏情况设计数据类型宁可多写两个字节不赌数据弱。这是刷题踩坑换来的经验笔试环境里没有调试机会稳健是第一优先级。6. 在线自测、随机对拍与三道高频变形题6.1 在线评测与自测方法笔试系统一般按“输入示例-输出示例”的格式做全量数据评测本地自测时最好手敲几组样例确认输出。除了前面表格里的三组基础样例再推荐几组专项自测负数混合4 / -5 -1 0 3排序后取中位数 -1代价 40149。全部相等的数组5 / 7 7 7 7 7代价 0。极端跨度2 / -1000000000 1000000000代价 2000000000正好验证 long 类型。每组样例跑完都对一下预期结果。这里多说一句笔试环境里如果系统报错不如预期优先检查输入解析而不是算法逻辑。很多“答案错误”其实是多读了空行、数组长度没对齐之类的小问题。6.2 随机数据对拍脚本比手敲样例更可靠的方式是对拍。写一个暴力枚举版本再写一个排序取中位数版本生成随机小数组对比两个版本的结果。代码不复杂但能一次性覆盖成千上万组边界情况比自己想测试用例全面得多。import randomdef brute(a): lo, hi min(a), max(a) best float(inf) for x in range(lo, hi 1): cost sum(abs(v - x) for v in a) best min(best, cost) return bestdef solve(a): b sorted(a) target b[len(b) // 2] return sum(abs(v - target) for v in b)for _ in range(10000): n random.randint(1, 8) a [random.randint(-5, 10) for _ in range(n)] if brute(a) ! solve(a): print(mismatch:, a, brute(a), solve(a)) break else: print(all ok)这里的关键是让暴力枚举的 range 不要太大所以随机数范围控制在 -5 到 10 之间。对拍一万组理论上能覆盖绝大多数边界形态包括奇偶长度、负数、全等数组。笔试前花五分钟写个对拍脚本比盯着代码反复读更有效。6.3 三道高频变形题全相等的变形在面试里出现频率很高核心都是绝对值距离最小化的变体。第一道变形只能对元素加 1不能减 1求最少操作次数。既然不能减目标值只能取数组最大值答案就是 sum(max(a)-a[i])。负数同样适用目标值依旧是最大值。第二道变形每次操作可以把相邻两个元素一个加 1、另一个减 1求使所有元素相等的最少操作次数。这个版本的核心是前缀和先判断总和能否被 n 整除不能则无解能则计算每个元素与平均值的差值累加前缀和的绝对值就是最少操作次数。原理在于每次相邻操作相当于移动一个单位的“差额”从左到右逐个抹平。第三道变形带权重的全相等每个元素有权重 w[i]求最小化 sum(w[i]·|a[i]-x|)。解法是把权重看成该位置有 w[i] 个重复点找加权中位数也就是前缀权重首次超过总权重一半的位置。这个变形在工程场景里更接近“选址问题”——在数轴上选一个仓库位置使所有客户的加权配送距离最小。变形题的意义在于中位数这一个结论能串起多个看似不同的题目。刷题时如果每道独立背代码很快就会忘理解了“绝对值距离最小化”这个模型变一个条件就能现场推一个解法出来这才是春招真正想看到的能力。最后再分享一个个人习惯每次写完这类“排序取中位数”的题我都会顺手在代码里保留一次暴力对拍的注释标注出关键样例和复杂度结论。笔试是限时游戏但准备阶段不是——把每道题的“为什么”拆透彻考场上才能毫不犹豫地写。全相等这道题不复杂但它值得认真对待因为它背后代表的建模能力恰恰是大厂算法岗最看重的底层素质。

相关新闻

Flink 1.11.1 自定义 Debezium JSON 解析方案

Flink 1.11.1 自定义 Debezium JSON 解析方案

1. 项目概述:为什么要在 Flink 1.11.1 中动 Debezium 的 JSON 格式?Flink 1.11.1 是一个承前启后的关键版本——它首次将 CDC(Change Data Capture)能力正式纳入 Flink SQL 原生支持体系,通过flink-connector-debezium…

2026/10/16 15:14:33 阅读更多 →
SQLAlchemy 2.0 核心概念与异步支持实战

SQLAlchemy 2.0 核心概念与异步支持实战

搞了这么多年 Python ORM,我越来越觉得 SQLAlchemy 2.0 是一套全新的心智模型,而不是 1.x 的小修小补。最被低估的其实是它把查询入口、映射声明、事务管理、加载策略全部收敛到同一套 API 上,异步支持(AsyncSession/AsyncEngine&…

2026/10/16 15:14:33 阅读更多 →
adb驱动工具集实战:Exynos4412开发板从驱动安装到adb shell打通

adb驱动工具集实战:Exynos4412开发板从驱动安装到adb shell打通

简介:adb驱动工具集面向Android应用开发者、系统调试人员及嵌入式爱好者,用于在电脑与Android设备之间建立稳定连接,完成数据传输、设备控制、日志查看与应用安装卸载等操作。该工具集特别针对友坚android210与Exynos4412处理器平台做了兼容优…

2026/10/16 15:14:33 阅读更多 →

最新新闻

挑选大健康消费品牌,别让营销包装掩盖真实产品实力

挑选大健康消费品牌,别让营销包装掩盖真实产品实力

国民健康消费意识持续提升,大健康赛道品牌持续针对不同人群推出蛋白营养、运动补给、功能性膳食等产品,覆盖健身爱好者、职场人群、中老年群体等多元消费群体。不少消费者在选购大健康产品时,很容易被宣传文案、精致外包装吸引,忽…

2026/10/16 15:50:12 阅读更多 →
一人公司的AI工作流,不是工具越多越有效

一人公司的AI工作流,不是工具越多越有效

很多人开始做一人公司后,都会经历一个阶段:注册很多AI工具,收藏大量教程,尝试不同模型,最后却发现每天的工作并没有明显变快。问题通常不在工具不够多,而在于没有形成稳定的工作流。一人公司的AI效率&#…

2026/10/16 15:50:12 阅读更多 →
YM Services文旅APP以垫付模式服务文旅商融合新生态

YM Services文旅APP以垫付模式服务文旅商融合新生态

​假日经济正在成为驱动城市文旅商深度融合的核心引擎。2026年8月,邯郸市第十六届人民代表大会常务委员会第四十次会议通过决议,提出强化顶层设计、深耕核心IP、深化业态融合、实施精准营销四大方向,推动工作重心从主要抓文旅活动管理向统筹培育假日经济全产业链转变。决议明确…

2026/10/16 15:50:12 阅读更多 →
国内GEO优化服务商横评:三家头部在信源、技术、价格上的十项对比

国内GEO优化服务商横评:三家头部在信源、技术、价格上的十项对比

国内GEO优化服务商横评:三家头部在信源、技术、价格上的十项对比国内 GEO 赛道到 2026 年 10 月已经跑出头部梯队,但市场上信息杂乱,企业很难一眼看出谁更适合自己。我们把传声港 GEO、传新社 GEO、怪兽智能 GEO 放在同一张评测表里&#xff…

2026/10/16 15:50:12 阅读更多 →
SKILLCOURT系统怎么样?2026年视觉认知训练系统报价与功能实测

SKILLCOURT系统怎么样?2026年视觉认知训练系统报价与功能实测

摘要2026 年,运动康复与竞技体育领域对"脑—身联动"量化评估的需求持续攀升,视觉认知训练系统已从科研实验室逐步走向临床康复与职业运动队。本文以 SKILLCOURT 系统为核心评测对象,从技术原理、功能模块、适用场景、国内服务支撑及采购路径等维度进行系统梳理,并结合…

2026/10/16 15:50:12 阅读更多 →
2026企业微信功能详细介绍:核心模块与适用场景解析

2026企业微信功能详细介绍:核心模块与适用场景解析

摘要:作为连接企业内部协同与外部客户生态的关键枢纽,企业微信已超越单纯的通讯工具范畴,成为组织数字化转型的基础设施。本文立足2026年最新产品形态,系统拆解“对内高效办公”与“对外客户运营”双核驱动模式,结合零售、教育、金融及政务等领域的实战案例,深度剖析其业务适配…

2026/10/16 15:49:12 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

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

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 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/15 0:14:36 阅读更多 →
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/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练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/16 14:23:36 阅读更多 →