LeetCode 171. Excel 表列序号
题目描述


题意分析
将 Excel 列名转为列序号,每个字母
A..Z对应数值1..26,越靠左的字母权重越大。这套编号没有表示 0 的字母,因此当前位的值是字母-'A'+1。
解法:按 26 进制累加
核心思路
[!blue]
列名的相邻两位权重相差 26 倍。若已经处理的前缀对应序号
ans,在右侧追加一个字母后,原来每一位都向高位移动一位,所以整个旧前缀的贡献变成ans*26;新字母处在最低位,再加上它的值value即可。因此从左到右反复执行
ans = ans*26 + value。初始ans = 0表示空前缀,每次更新后都得到当前前缀的序号,读完全部字母便是答案,不需要反转字符串或计算幂。这里与普通进制转换的区别只在数位取值:字母对应
1..26,不能映射成0..25,也不需要使用反向转换列名时的减一操作。
解题步骤
- 初始化
ans = 0,表示尚未读入字符的空前缀。- 从左到右遍历列名,将当前字符映射为 1 到 26。
- 执行
ans = ans * 26 + value,使ans等于当前已读前缀的序号。- 遍历结束后返回
ans。
代码实现
class Solution {
public int titleToNumber(String columnTitle) {
int ans = 0;
for (int idx = 0; idx < columnTitle.length(); idx++) {
int value = columnTitle.charAt(idx) - 'A' + 1;
// 旧前缀提升一位,再加入从一开始编号的当前字母。
ans = ans * 26 + value;
}
return ans;
}
}
func titleToNumber(columnTitle string) int {
ans := 0
for idx := 0; idx < len(columnTitle); idx++ {
value := int(columnTitle[idx]-'A') + 1
// 旧前缀提升一位,再加入从一开始编号的当前字母。
ans = ans*26 + value
}
return ans
}
复杂度分析
- 时间复杂度:$O(n)$,
n为列名长度,每个字符只处理一次。- 空间复杂度:$O(1)$,只维护累加结果和当前字符值。
关键点总结
[!green]
A映射为 1,Z映射为 26;字母表里没有表示 0 的数位。- 从高位到低位使用“旧值乘基数再加新位”,可以省去反转、求幂和额外存储。
- 题目保证答案不超过
2147483647;累加过程中每次结果都不超过最终答案,使用int足够。
易错点总结
[!yellow]
- 忘记字符映射中的
+1,会把整套从 1 开始的编号错当成从 0 开始。- 当前递推要求从左往右读取;乘 26 的对象是已经处理的前缀,不能写成
ans + 26*value。- 不要套用反向转换列名时的“先减一”规则,这里直接累加每个字母对应的
1..26。
相似题目
| 题目 | 难度 | 关联与区别 |
|---|---|---|
| 168. Excel 表列名称 | 简单 | 反向转换把数值生成列名,本题按26倍累积,每个字母贡献1到26而非0到25。 |
转载与许可
许可
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!