题目:
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
Brute Force:
思路:
计算title相当于一个26进制转换问题,超过26则增加字母位数。A在个位表示1,在十位表示1*26.
考虑从个位开始计算,通过取余得到对应字母,之后再反转字符串。
本质是进制转换,将n转化为26进制,转化过程如下(括号里的是26进制数):
1->(1)->A
2->(2)->B
...
26->(10)->Z
27->(11)->AA
28->(12)->AB
.....
52->(20)->AZ
53->(21)->BA
但是超出存储空间。
Attention:注意考虑字母Z,26%26 = 0,并不对应'Z'. 所以取余时除数用27. 好比十进制 0~9,计算时取余除数取10.
错误的,26进制还是需要除以26,0~9是十个数,只不过z要单独考虑。Z是末尾,而十进制从0开始,取余没问题。这就是两者区别。【后面修改】
Submission Result: Memory Limit Exceeded (原因,使用reverse)
Error Code:
class Solution {
public:
string convertToTitle(int n) {
string ret;
if(n < 0) return NULL;
/* 由于asc码刚好对应 所以不需要map存储
map<int, char> convertmap;
//A~Z的asc码刚好是1~26
for(int i = 1 ; i <= 26; i++)
{
convertmap.insert((i, itoa(i)));
}
*/
while(n)
{
int tmp = n % 27;
ret += (tmp + '0');
if(n > 26)
{
n /= 26;
}
}
reverse(ret.begin(), ret.end());
}
};
修改的代码
Attention:
1. 注意若为26倍数,需要将n 减1. 否则会得到如下结果
if(tmp == 0)
{
str += 'Z';
n--; //26/26为1,但是不应该进位,‘Z’可以表示
}
n /= 26;
<span style="font-weight: bold; font-size: 14px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">会产生进位。</span>
Submission Result: Wrong AnswerMore Details
Input: | 26 |
Output: | "AZ" |
Expected: | "Z" |
if(tmp == 0)
{
str += 'Z';
n--;
}
3.使用reverse会超出leetcode要求的空间限制。积累下如何正确反转字符串。
//反转
string result;
for(int i=str.size()-1;i>=0;i--){
result+=str[i];
}
4. 注意从整数到字母的转换,必须指出转成字母,而不能简单转成字符串的ASC码。否则将得到如下结果。
Error:
str += '0' + tmp ;
Correct:
str += 'A' + tmp - 1;
Submission Result: Wrong AnswerMore Details
Input: | 1 |
Output: | "1" |
Expected: | "A" |
class Solution {
public:
string convertToTitle(int n) {
string ret, str;
if(n < 0) return ret;
while(n)
{
int tmp = n % 26;
n /= 26;
if(tmp == 0)
{
str += 'Z';
n--;
}
else
{
str += 'A' + tmp - 1;
}
}
for(int i = str.size()-1; i >= 0; i--)
{
ret += str[i];
}
return ret;
}
};
总结,对于问题的分析到位,可是一些细节考虑不是很全面,还需要积累经验。遇到问题,还应该多分析区别和相同点,这样才能抓住要害,不至于出错。比如本题虽然是26进制转换,但是与10进制转换还是有些区别的,需要根据区别来编程。
一种不需要反转字符串的方法,把每次得到的字母放在ans前面即可。
ans = char ((n - 1) % 26 + 'A') + ans; 注意相加的顺序。字符串相加顺序影响结果。
class Solution {
public:
string convertToTitle(int n) {
string ans;
while (n) {
ans = char ((n - 1) % 26 + 'A') + ans;
n = (n - 1) / 26;
}
return ans;
}
};