LeetCode171、Excel 表列序号

116 阅读2分钟

LeetCode 系列记录我学习算法的过程。

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情

题目

给你一个字符串 columnTitle ,表示 Excel 表格中的列名称。返回 该列名称对应的列序号 。

例如:

A -> 1
B -> 2
C -> 3
...
Z -> 26
AA -> 27
AB -> 28 
...

示例:

输入: columnTitle = "A"
输出: 1


输入: columnTitle = "AB"
输出: 28


输入: columnTitle = "ZY"
输出: 701

提示:

  • 1 <= columnTitle.length <= 7
  • columnTitle 仅由大写英文组成
  • columnTitle 在范围 ["A", "FXSHRXW"] 内

思路

这个题目和之前一个求 Excel 表列名称的题目很类似,那个是根据传入的数值求字符串

这个是根据传入的字符串求数值,所以思路也差不多,都是按照 26 进制的来求解:

  • 首先我们定义一个字符与数字的映射表 map
  • 然后定义一个存储结果的变量 sum,然后遍历字符串
  • 字符串每一项的值都是当前字符映射值乘于 26n - 1 次方,例如个位是 0 次方,百位是 2 次方,由于遍历的方向和位数不同,所以要做处理 len - i - 1
  • 将每一项求出来的结果与记录的结果相加
  • 最后返回相加后的值即可

代码实现

/**
 * @param {string} columnTitle
 * @return {number}
 */

var titleToNumber = function(columnTitle) {
    // 定义一个字符与数字的映射表
    const map = { "A": 1, "B": 2, "C": 3, "D": 4, "E": 5, "F": 6, "G": 7,
        "H": 8, "I": 9, "J": 10, "K": 11, "L": 12, "M": 13, "N": 14,
        "O": 15, "P": 16, "Q": 17, "R": 18, "S": 19, "T": 20,
        "U": 21, "V": 22, "W": 23, "X": 24, "Y": 25, "Z": 26
    }
    // 存储结果
    let sum = 0
    // 遍历传入的字符串
    for(let i = 0, len = columnTitle.length; i < len; i++) {
        // 进制是26进制,所以当前位计算是 26 的 n-1 次方 * 当前位的映射值
        sum += (Math.pow(26, len - i - 1) * map[columnTitle[i]])
    }
    // 最后返回结果
    return sum
};

image.png

优化

也可以不定义映射表,直接根据字符及ASCII码来获取映射值

var titleToNumber = function(columnTitle) {
    // 获取 A 的 ASCII 码
    let temp = 'A'.charCodeAt(), sum = 0
    // 遍历计算
    for(let i = 0, len = columnTitle.length; i < len; i++) {
        // 当前项的 ASCII 码减去 A 的 ASCII 码再加 1 就是映射值
        sum += (Math.pow(26, len - i - 1) * (columnTitle[i].charCodeAt() - temp + 1))
    }
    // 返回结果
    return sum
};

image.png