题目如下:
Given a positive integer, return its corresponding column title as appear in an Excel sheet.
For example:
1 -> A
2 -> B
3 -> C
...
26 -> Z
27 -> AA
28 -> AB
给定数字,然后将数字转化为Excel表中sheet的列标题(column title)样式。
看似很简单,其实还是有一些坑的。因为未经处理前,这并不是一个严格意义上关于26进制转换的问题,因为禁止转换一般是从0开始的,这里的最小值则是1即“A”,所以直接按照10进制那样转化的话会出现问题,比如下面的代码就是有问题的:
public String convertToTitle(int n) {
String result = "";
while(n>0){
int k = 64+n%26;
char a = (char)k;
result = a + result;
n = n/26;
}
return result;
}
你会发现根本表示不了“Z”,然后你千方百计把“Z”弄了出来。比如下面改进后的代码:
public String convertToTitle(int n) {
String result = "";
while(n>0){
int k;
boolean flag = (n%26 == 0);
if(flag){
k = 90;
}else{
k = 64+n%26;
}
char a = (char)k;
result = a + result;
n = n/26;
}
return result;
}
这下倒是能表示“Z”了,但是你发现加入你输入的是52,本来应该输出的是“AZ”,但是现在却输出的是“BZ”。这里是为什么呢?我们看一下52的构成,26*1+1*26=52.我们第一次进行将52进行除26操作后,发现是可以被整除的,这说明最后一位一定是“Z”。而一个“Z”就代表一个26,52/26=2,说明52是由2个26组成的,而我们的“Z”已经提供了一个26,所以剩下只还有1个26需要提供,故要在这个整除了26的n结果的基础上再“减一”,这样才是后面的位需要提供的26的真实数量。所以,正确已Accepted的代码如下:
public String convertToTitle(int n) {
String result = "";
while(n>0){
int k;
boolean flag = (n%26 == 0);
if(flag){
k = 90;
}else{
k = 64+n%26;
}
char a = (char)k;
result = a + result;
n = n/26;
if(flag){
n --;
}
}
return result;
}
然后是评论区的代码,先转化为真正的26进制,然后就和10进制一样了,代码如下所示:
public String convertToTitle(int n) {
if (n == 0) {
return "";
}
int div, rem;
div = (n-1)/26;
rem = (n-1)%26;
return convertToTitle(div) + (char)('A'+rem);
}
这里解释一下为什么要“减一”,因为变成真正的26进制(0-25)后,你会发现和之前的伪26进制相比(即1-26),只有最后一位在计算的时候才会出现偏差。举个例子AA,你如果按真正的16进制算呢,就是26*1+0 = 26,而你按伪26进制算就是26*1+1=27。所以,为了每次都是按真正的26进制进行计算,我们需要在求商和余数之前先对n进行“减一”操作。