题目描述

✅ 168. Excel 表列名称

image-20260928202113679

image-20260928202113680

题意分析

给定从一开始的正整数列编号,返回它对应的 Excel 列名称。列名称只使用大写字母,每一位的 A 到 Z 表示数值 1 到 26,超过一位能表示的范围后向更高位进位。

关键区别是这里没有表示零的字母。普通二十六进制的每位范围是 0..25,不能直接把列编号取模后照搬普通进制转换。需要确定最低位的字母,以及去掉这一位后剩余的高位编号。

解法:减一后按 26 进制转换

核心思路

[!blue]

设当前编号为 N,剩余高位编号为 q,最低位字母的数值为 r。它们满足 N = 26q + r,但这里 r 的范围是 1..26,而普通整除的余数范围是 0..25。

将等式两边减一,得到 N - 1 = 26q + (r - 1)。此时 r - 1 正好落在 0..25,所以 (N - 1) % 26 就是当前字母相对 A 的偏移,(N - 1) / 26 就是剩余高位编号。减一不是单独修正某个边界,而是把整套数位规则转换到普通整除能处理的范围。

每次剥掉一个最低位后,高位部分仍然使用同样的列名规则,因此每轮都要先减一,再用减一后的值取模和整除。不能只在最初减一次,也不能取模用新值、整除却用旧值。

生成字符的顺序是从最低位到最高位,追加到缓冲区后需要整体反转。编号变成零时说明高位已经全部处理完,循环结束。

解题步骤

  1. 创建字符缓冲区,用来按低位到高位保存字母。
  2. 当 columnNumber > 0 时,先将它减一。
  3. 用 columnNumber % 26 得到 0..25 的偏移,追加对应的大写字母。
  4. 用 columnNumber /= 26 去掉已经处理的最低位,继续处理高位。
  5. 反转缓冲区并返回字符串。

代码实现

class Solution {
    public String convertToTitle(int columnNumber) {
        StringBuilder ans = new StringBuilder();

        while (columnNumber > 0) {
            // 每位没有零编码,先减一再取余,才让一至二十六映射到字母。
            columnNumber--;
            ans.append((char) ('A' + columnNumber % 26));
            columnNumber /= 26;
        }

        return ans.reverse().toString();
    }
}
func convertToTitle(columnNumber int) string {
    ans := make([]byte, 0)
    for columnNumber > 0 {
        // 每位没有零编码,先减一再取余,才让一至二十六映射到字母。
        columnNumber--
        ans = append(ans, byte('A'+columnNumber%26))
        columnNumber /= 26
    }

    for left, right := 0, len(ans)-1; left < right; left, right = left+1, right-1 {
        ans[left], ans[right] = ans[right], ans[left]
    }
    return string(ans)
}

复杂度分析

  • 时间复杂度:O(d),其中 d 为结果列名的字符数。每轮生成一个字母,最后反转也遍历 d 个字符。
  • 空间复杂度:O(d),保存字符缓冲区和结果字符串。

关键点总结

[!green]

  • 先写出 N = 26q + r、1 <= r <= 26,就能自然推导出每轮减一的原因。
  • 减一后的商和余数分别表示高位编号与当前字母偏移,二者必须使用同一个调整后的数值。
  • 逐次取模得到的是逆序字符,输出前需要反转。

易错点总结

[!yellow]

  • 按普通进制直接取模:零余数对应的应当是本位的 Z,而不是另一个零数位;先减一可统一处理。
  • 只调整余数、不调整商:最低位得到字母后,高位仍可能多保留一次进位,必须在取模和整除前共同减一。
  • 只在循环外减一:高位也使用 1..26 的规则,每处理一位都需要重新调整。
  • Java 不转为 char:'A' + offset 是整数表达式,直接追加会调用追加整数的方法。
  • 忘记反转或在归零后继续循环:前者会颠倒位序,后者会处理不存在的高位。

相似题目

题目 难度 关联与区别
171. Excel 表列序号 简单 互为转换方向,本题需要处理没有零数码的26进制,取余前先减一。
补充题 145. 有符号整数的进制转换 中等 同样反复除基数生成数位,但普通进制有0,Excel列名用1到26表示字母。
转载与许可
作者
链接 https://hgnulb.github.io/blog/2024/94254549
许可 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!