「前端刷题」168.Excel表列名称(EASY)

120 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情

题目(Excel Sheet Column Title)

链接:https://leetcode-cn.com/problems/excel-sheet-column-title
解决数:944
通过率:43.7%
标签:数学 字符串 
相关公司:microsoft google amazon 

给你一个整数 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

思路

  1. 观察答案的位数,1位的有26个(A到Z),2位的有26^2个(AA到ZZ),3位的有26^3个(AAA到ZZZ),k位的有26^k个。
  2. 观察3位数的答案(AAA到ZZZ),其实和3位以内的26进制数(0到ppp,其中a是10,p是25)是一一对应的,都是26^3个。

因此有如下思路

  1. 先求出答案的位数k
  • 第一个k位数(AA..A)的前面有26 + 26^2 + ... + 26^(k-1)个数
  • 所以第一个k位数对应的数字为1 + 26 + 26^2 + ... + 26^(k-1) = (26^k - 1) / (26 - 1) = (26^k - 1) / 25
  • 如果输入n的答案是k位,则 (26^k - 1) / 25 <= n < (26^(k+1) - 1) / 25
  • 已知n求k,为避免浮点数误差,js代码为:Math.floor(Math.log((n + 0.5) * 25 + 1) / Math.log(26))
  1. 用输入n减去第一个k位数对应的数字得到m,m就是前面提到的k位以内的26进制数
  • m = n - (26^k - 1) / 25
  • 例如
    • n=1时,k=1,m=n-(26^1-1)/25=0(26进制的0,对应答案A)
    • n=26时,k=1,m=n-(26^1-1)/25=25(26进制的p,对应答案Z)
    • n=27时,k=2,m=n-(26^2-1)/25=0(补成2位的26进制即为00,对应答案AA)
    • n=702=26+26^2时,k=2,m=n-(26^2-1)/25=675(26进制的pp,对应答案ZZ)
    • n=703时,k=3,m=n-(26^3-1)/25=0(补成3位的26进制即为000,对应答案AAA)
  1. 将m转成26进制并在前面补上0成为k位,并将09转成AJ,将ap转成KZ即可得到答案
const log26 = Math.log(26)

function convertToTitle(n) {
    const k = Math.floor(Math.log((n + 0.5) * 25 + 1) / log26) // 答案有k位
    const res = (n - (26 ** k - 1) / 25).toString(26).padStart(k, '0').replace(/./g, x => {
        x = x.charCodeAt()
        return x <= 57 ? String.fromCharCode(x + 17) : String.fromCharCode(x - 22)
    })
    return res
}

171题是这道题的逆向题