Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题目描述:
给你一个整数 columnNumber ,返回它在 Excel 表中相对应的列名称。
例如:
A -> 1
B -> 2
C -> 3
...
Z -> 26
AA -> 27
AB -> 28
...
示例 1:
输入:columnNumber = 1
输出:"A"
示例 2:
输入:columnNumber = 28
输出:"AB"
示例 3:
输入:columnNumber = 701
输出:"ZY"
示例 4:
输入:columnNumber = 2147483647
输出:"FXSHRXW"
提示:
1 <= columnNumber <= 231 - 1
思路分析:
核心思路:
26个字母可以理解为 26 进制,即把10进制转换成 26 进制的各位。
用给的整数算出各位的ASCII码,转换成字母即可。
EXCECL的列是26个字母的顺序组合:
A - Z
AA - ZZ
AAA - ZZZ
...
A-Z 是 第 1 列 到第 26 列 AA - AZ 是第 27 列到第 52 列 BA - BZ 是第 53 列到第 78 列 ...
A - Z 的 ASCII码是 65 到90
- 先来说一下 A - Z,我们可以循环对 26 取余,第 1 列到第 25 列,取余后是 1 - 25。
最后(第 5 步)然后再转换成 ASCII 码(余数 + 65 - 1),再转换成字符串即可。 第 26 列对 26 取余,直接整除没有余数,所以整除的情况,直接使用 26 转换成 ASCII 码即可。 - AA 开始是一样的,AA 是 Z 后面的第一列,前面 26 列已经计算完了,所以从 27 列开始,应该是后面还有多少个 26 列,就有多少个 A - Z。
AA - AZ 就是第 2 个 26 列,BA - BZ 就是第 3 个 26 列,依次类推。
有多少个 26 列,计算时就是应该 除以 26 ,得出来的值就是多少个。 - 从 AAA 开始,就是有多少个 26 * 26 了,所以需要在前面的基础上再除以 26 。
因为计算 AA - ZZ 时已经除过一次 26 了,所以计算 AAA - ZZZ 时再除以 26 即可。
这么理解有些麻烦,可以理解为 26 进制。
所以 AA 列开始,就是把给的整数除以 26 之后再进行前一位字母的计算过程,对于整除的情况,和 1 中一样计算即可。 - 依次除以 26 进行计算,当除法运算结果为 0 时,说明已经计算完成。
- 各字母位的数字转换成 ASCII 码(余数 + 65 - 1),再转换成字符串,然后连接起来即可。
AC 代码:
golang :
// Excel表列名称
func convertToTitle(columnNumber int) string {
// 26个字母
const cntLetter = 26
// 结果
var result string
// 用于计算字母编码的切片
var ch []int
idx := columnNumber
for idx > 0 {
// 求余数
tail := idx % cntLetter
if tail == 0 {
// 整除无余数,则用 26 来计算编码
ch = append(ch, cntLetter)
// 先减去26,再取整数部分进行下一次循环
idx = (idx - cntLetter) / cntLetter
} else {
// 余数 用来计算编码
ch = append(ch, tail)
// 取整数部分进行下一次循环
idx = idx / cntLetter
}
}
// 循环切片,通过ASCII码计算出对应的字母后进行连接
for _, v := range ch {
result = string(v+65-1) + result
}
return result
}
总结:
该题的解答是之前写 VBA 工具的时候,需要将列值转换为列名称的逻辑。
当时一时也没想出来什么好办法。一个同事说用 ASCII 码,然后就打开思维了。
看到力扣上有这么一道题,就把当年 VBA 的代码转成了 go 语言。