题目描述(简单难度)

把数字根据对应规则转为字母。

解法一

这道题的话本质上其实就是进制转换,把 进制转为 26 进制表示,可以看一下 对进制转换有个更深的了解。

先讨论一下我们熟悉的 10 进制和 16 进制的转换。

16 进制中,09 还是正常的数字,然后增加字母 A 表示 10,字母 B 表示 11… 以此类推,直到 F 表示 15,所以我们各个位的取值范围是 0 - 15

假如 16 的进制的 A1F 转换为 10 进制的话就用下边的式子,其中 A 表示 10F 表示 15

那么假如我们知道的是 10 进制的 2591,怎么转为 16 进制呢?

我们把上边的等式一般化,设我们要求的每一位分别是 x1,x2,x3...,事先我们并不知道有多少位。

168. Excel Sheet Column Title - 图1

我们可以在等式两边同时模上 16,等式就变成

168. Excel Sheet Column Title - 图2

和之前对比, 16 的幂都小了 ,同时 x1 消失了。

接下来就可以重复上边的两个步骤,模 16 和除以 16,就可以依次求出 x2x3 …了。

直到除以 16 后变成 0 ,就可以结束了。

对于 10 进制转 26 进制的话是一样的道理,只不过每次采用模 26 和除以 26

所以代码的话,可以直接写出来。

上边 (char) ('A' + c - 1) 这里的话,算是一个技巧,我们是通过对 A 的偏移,强制将整数转为了字符。

比如 c = 3,那么 'A' + c - 1,会把 A 根据 ASCII 码值转为 65,然后计算 65 + c - 1 = 65 + 3 - 1 = 67,然后 (char)67,根据 ASCII 码值就刚好是字符 C

但是上边的算法还是有问题的,因为题目中每个位的范围是 1-26,而不是0-25

所以取余的话对于 1-25 的数字结果都是正确的,但如果当前的位是 26,余数求出来就是 0,此时我们需要把它修正为 26

此外,我们每次除以 26 是为了把最低位去掉,回忆下之前的等式

因为 x1 的范围正常情况下是 0-25 ,所以除以 26 可以把 x1 去掉,但这道题的范围是 1-26,当 x1 是 的时候,除以 26 后等式会变成下边的样子

所以当我们再模 26 去求 x2 的话就会发生错误。

修改的话,当我们发现当前位是 26 的时候,我们应该在等式两边减去一个 1

168. Excel Sheet Column Title - 图3

这样两边再同时除以 26 的时候,就可以把 x1 去掉了。

代码修正后如下。

  1. public String convertToTitle(int n) {
  2. StringBuilder sb = new StringBuilder();
  3. int c = n % 26;
  4. if(c == 0){
  5. c = 26;
  6. n -= 1;
  7. sb.insert(0, (char) ('A' + c - 1));
  8. n /= 26;
  9. }
  10. return sb.toString();

这道题看做是进制转换问题的变形,只要知道进制转换的原理,改这道题的话也不难。

区别就在于题目规定的数字中没有 0 ,换句话讲,正常的 26 进制本应该满 261,然后低位补 0,但是这里满 26 的话就用 26 表示。满 27 的时候才会向前进 1,然后低位补 1。所以 Z(26) 的下一个数字就是 A(1)A(1),即 27 对应 。

添加好友一起进步~

如果想系统的学习数据结构和算法,强烈推荐一个我之前学过的课程,可以点击 这里 查看详情