这是我参与更文挑战的第 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 进制数可以表示为:
如果我们对等号两边同模 26,则可以得到 的值。接着对等号两边同除 26,那么就将 项给消除掉了,上式就变成了:
所以我们可以对上式不断进行 同模 和 同除 的操作,每一次获取和消去最低项,直到 变为 0 即可。
另外本题值得注意的一点是,题目中的列名称是没有 0 的。本来数值到了 26 之后,应该进位同时低位补 0 的,但是本题中 26 就对应着字母 Z。
所以 , , , ... 的取值范围是 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;
}
};