Leetcode - Excel表列名称

178 阅读1分钟

这是我参与更文挑战的第 29 天,活动详情查看更文挑战

题目描述

给你一个整数 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 进制数可以表示为:

a1×260+a2×261+a3×262+a4×263+...=na_1 \times 26^0 + a_2 \times 26^1 + a_3 \times 26^2 + a_4 × 26^3 + ... = n

如果我们对等号两边同模 26,则可以得到 a1a_1 的值。接着对等号两边同除 26,那么就将 a1a_1 项给消除掉了,上式就变成了:

0+a2×260+a3×261+a4×262+...=n/260 + a_2 \times 26^0 + a_3 \times 26^1 + a_4 \times 26^2 + ... = n / 26

所以我们可以对上式不断进行 同模 和 同除 的操作,每一次获取和消去最低项,直到 nn 变为 0 即可。

另外本题值得注意的一点是,题目中的列名称是没有 0 的。本来数值到了 26 之后,应该进位同时低位补 0 的,但是本题中 26 就对应着字母 Z。 所以 a1a_1, a2a_2, a3a_3, ... 的取值范围是 1 - 26(对应A - Z),而对 26 取模的范围是 0 - 25。这就会导致 26 对 26 取模为 0,并且两边同除 26 时,不能够消除掉最低项(26 / 26 = 1)。 为了解决这个问题,可以在同模和同除操作中,先让 n 减去 1。这样就可以保证上式不断获取和消去最低项过程的正确性了。

代码

C++

class Solution {
public:
    string convertToTitle(int columnNumber) {
        int n = columnNumber;
        string ans;
        while (n > 0) {
            ans += (n - 1) % 26 + 'A';
            n = (n - 1) / 26;
        }
        reverse(ans.begin(), ans.end());
        return ans;
    }
};

另一种写法

class Solution {
public:
  string convertToTitle(int columnNumber) {
    string res;
    while (columnNumber > 26) {
      res = (char)('A' + (columnNumber - 1) % 26) + res;
      columnNumber = (columnNumber - 1) / 26;
    }
    return (char)('A' + columnNumber - 1) + res;
  }
};