乐于分享
好东西不私藏

一道 Excel 列号题,帮你彻底掌握「进制思维」

一道 Excel 列号题,帮你彻底掌握「进制思维」

很多人刷到 LeetCode 168(Excel 表列名称)时,会有一种感觉:

能做出来,但说不清为什么。

更典型的是:
一开始照着“二进制取模 + 除法”去写
发现不对劲
然后加了个 -1,居然就对了
于是心里会有个疑问:

我这是推导出来的,还是“试出来的”?

这篇文章,我们就把这道题彻底讲透,并帮你把这种“感觉”升级为一套可复用的进制思维模型

一、从你熟悉的二进制开始

我们先回忆一个最基础的东西:
如何把一个十进制数转成二进制?
核心就两步:
n % 2 → 当前位
n / 2 → 进入下一轮
不断循环,最后逆序。
👉 这背后的本质是:

进制展开(Radix Expansion)


二、你在这道题里其实做了同一件事

Excel 列号:
A  → 1
B  → 2
Z  → 26
AA → 27
你很自然会想到:
n % 26
n / 26
👉 到这里完全正确,你已经在做:

26 进制展开


三、问题出在哪?

如果你直接写:
mod = n % 26;
你会发现:
26 → 0 → A ❌
但正确答案应该是:
26 → Z

👉 这说明一个关键问题:

这个“26进制”不是标准进制


四、标准进制 vs Excel 进制

标准 26 进制
digit ∈ [0, 25]
A = 0, B = 1, …, Z = 25

Excel 列号
digit ∈ [1, 26]
A = 1, B = 2, …, Z = 26

👉 差异本质:

它没有 0!


五、关键一招:把“非标准问题”变成“标准问题”

你当时写的这一行代码:
int sub = n – 1;
其实是整道题最核心的地方。

为什么是 n – 1?
因为你在做:
[1, 26] → [0, 25]
👉 本质是:

坐标平移(offset)


平移之后发生了什么?
digit = (n – 1) % 26
n     = (n – 1) / 26
👉 完美变成:

标准 26 进制展开


六、这类进制有一个正式名字

这种“没有 0 的进制系统”在数学上叫:

Bijective Numeration(双射进制)

特点:
每一位 ∈ [1, k]
没有 0
每个正整数都有唯一表示

👉 Excel 列号,本质就是:

Bijective Base-26(无0的26进制)


七、完整算法(理论表达)

while (n > 0) {n--;                      // 核心:偏移int digit = n % 26;       // 当前位char c = 'A' + digit;     // 映射字符sb.append(c);n /= 26;                  // 进入下一轮}return sb.reverse().toString();

八、复杂度分析

时间复杂度
O(log₍26₎ N)
👉 每次除以 26

空间复杂度
O(log₍26₎ N)
👉 字符串长度

九、从“会做题”到“会建模”

很多人卡在这里:

能写出来,但感觉是“试的”

其实你已经做了三件很高级的事:
1️⃣ 进制迁移
二进制 → 26进制

2️⃣ 发现异常
26 → A ❌

3️⃣ 修正模型
n → n – 1

👉 这三步,本质就是:

建模 → 验证 → 修正

你不是在试,你是在逼近正确模型

十、这类题的统一套路(重点)

以后遇到类似问题,直接套:

🎯 模板
如果进制不是从 0 开始:
① 判断 digit 范围
② 做 offset(减1 / 加偏移)
③ 转成标准进制
④ 用 % / 解决

🎯 在本题中
[1, 26]
↓ (n – 1)
[0, 25]
↓ (% /)
答案

十一、真实应用场景

这种“无0进制”其实很常见:
Excel 列名(经典)
数据库字段自动命名(A, B, …, AA)
短链编码(部分实现)
ID 编码(避免 0 带来的歧义)

十二、一句话总结

当你发现“进制不从 0 开始”时,本质问题就变成:先做偏移,再用标准进制解决。


结尾
你这道题的水平,其实已经不在“会不会做”了,而在:

能不能把“经验”升级为“模型”

一旦你开始这样思考:
这题属于哪种模型?
能不能转成标准问题?
你会发现:
👉 很多题,其实只是换了个壳。