问题:
难度:easy
说明:
按照 excel 的行列字母规则,生成指定数字的字母。
题目连接:Loading...
输入范围:
1 <= columnNumber <= 2^31 - 1
输入案例:
Example 1:
Input: columnNumber = 1
Output: "A"
Example 2:
Input: columnNumber = 28
Output: "AB"
Example 3:
Input: columnNumber = 701
Output: "ZY"
Example 4:
Input: columnNumber = 2147483647
Output: "FXSHRXW"
我的代码:
有点比较绕的地方就是 A ~ Z 代表 1 ~ 26 ,然后 AA 就直接代表 27 了,这里就意味着 并不是直接使用 26 进制就能处理的地方,因为 A 是 1,Z 是 26 , 而 26 + 1 就是 AA , Z 和 AA 之间少了一个 作为 0 表示的字母.
那么就得每次进制处理时候,先提前 - 1 是为了去掉 0 这个不存在的间隔,而且 26 进制的求模,还得把 0 改为 Z 处理。
class Solution {
private static char[] letters;
static {
letters = new char[26];
letters[0] = 'Z'; // 单独把 z 放到 0 处
for(int i = 1, c = 'A'; i < 26; i ++, c ++) {
letters[i] = (char) c;
}
}
public String convertToTitle(int cn) {
StringBuilder builder = new StringBuilder();
while(cn > 0) {
int mod = cn % 26; // 求模
builder.insert(0, letters[mod]);
cn = (cn - 1) / 26; // 额外 - 1 再除
}
return builder.toString();
}
}
另一版比较绕的逻辑,就是为了绕开 0 这个逻辑,取上一次运算的MOD,然后判断当前位的数值是否多出了 1:
class Solution {
private static char[] letters;
static {
letters = new char[26];
letters[0] = 'Z';
for(int i = 1, c = 'A'; i < 26; i ++, c ++) {
letters[i] = (char) c;
}
}
public String convertToTitle(int cn) {
StringBuilder builder = new StringBuilder();
int preMod = -1;
while(cn > 0) {
int mod = cn % 26;
builder.insert(0, preMod == 0 ? letters[(mod - 1 + 26) % 26] : letters[mod]);
cn = cn == 26 || (cn == 27 && preMod == 0) ? 0 : cn / 26;
preMod = mod;
}
return builder.toString();
}
}