Excel 表列序号

标签: 数学 字符串

难度: Easy

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

例如:

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

示例 1:

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

示例 2:

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

示例 3:

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

提示:

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

Submission

运行时间: 20 ms

内存: 16.0 MB

class Solution:
    def titleToNumber(self, columnTitle: str) -> int:
        num = 0
        for c in columnTitle:
            num *= 26
            num += ord(c) - 64
        return num

Explain

这个解法的思路是将字符串从左到右遍历,把每个字符视为26进制的一位数。遍历时,不断将之前的结果乘以26,再加上当前字符代表的数值。其中字符到数值的转换通过 ASCII 码实现,即用字符的 ASCII 码减去大写字母 A 的 ASCII 码 64。最终遍历完整个字符串,得到的结果就是列名称对应的列序号。

时间复杂度: O(n)

空间复杂度: O(1)

class Solution:
    def titleToNumber(self, columnTitle: str) -> int:
        num = 0
        for c in columnTitle:
            # 将之前的结果乘以 26
            num *= 26
            # 将当前字符转换为数值,加到结果上 
            num += ord(c) - 64
        return num

Explore

在这个算法中,我们需要将字符 'A' 转换为数值 1,而不是传统的 0,因为 Excel 列序号是从1开始计算的(即 'A' = 1, 'B' = 2, ..., 'Z' = 26),而不是从0开始。因此,我们使用 `ord(c) - 64` 来转换,这样 'A' 的 ASCII 码 65 减 64 就得到 1。如果使用 `ord(c) - 65`,则 'A' 会被错误地映射为 0。

Excel的列名通常按照26进制计算,最大长度为7意味着可以表示从 'A' 到 'ZZZZZZZ' 的所有列。要计算最大列名对应的数值,我们可以理解每一位都取最大值 'Z',即 26。因此,最大列名 'ZZZZZZZ' 对应的数值是 26^7-1 (因为每一位都是26的幂次累计)。这个结果是非常大的,可以覆盖Excel的所有可能列。

虽然理论上可以考虑并行处理或向量化操作来加速计算,但实际上这种类型的问题(将列名转换为数字)通常涉及的数据量较小,且序列依赖性较强(每一步的计算依赖于前一步的结果),这使得并行化或向量化的潜在优势不明显。因此,传统的串行处理通常已足够快速且简单。

当前的代码并未直接处理非法输入,如小写字母或特殊字符。如果输入包含这类字符,计算结果可能会不正确或引发错误。在实际应用中,应该增加输入验证,确保所有字符都是大写字母A到Z之间。可以通过检查输入字符串中的每个字符是否在 'A' 到 'Z' 的范围内,来提前拦截并处理非法输入。