Palindrome Number
https://leetcode.com/problems/palindrome-number/
给定一个整型数,判断这个数是否为回文数
我们根据例子很容易得出,负数不是回文数,一位正整数肯定是回文数。
Solution1
首先用最简单的方法,把数字转换成字符串,从两边向中间依次判断对应位的数字是否相等。
class Solution {
public:
bool isPalindrome(int x) {
if (x < 0) {
return false;
}
if( x == 0) {
return true;
}
std::string str = to_string(x);
int middle = str.length()/2;
for (int i = 0; i < middle; ++i) {
if(str[i] != str[str.length() - 1 - i]) {
return false;
}
}
return true;
}
};
Solution2
题目的最后问能否不通过转换成字符串的方式解决这个问题,那就尝试一下吧。不通过字符串,其实我们还是要从两边到中间依次比较对应位的数字。那么问题来了,如何依次取得左右两边的数字呢?
我们以 12341 这个数字为例,想要获得最低位数字 1 很简单只要12341 % 10
就得到了。那么如何获得最高位数字 1 呢?我们发现12345/10000 -> 1
,也就是说用这个数除以 10^4
就行了,其中的 4 是 12341 的位数 5 减去 1。我们可以通过循环 / 10
的方式取得一个数字的位数。
12341 % 10 -> 1
12341 / (10 ^ 4) -> 1
当我们比较取得的最高位和最低位之后,发现是相等的,要继续循环,需要把原来的这个数字掐头去尾。我们来看看如何实现:
12341 % (10 ^ 4) -> 2341
2341 / 10 -> 234
也就是说,我们可以通过把这个数先 % (10 ^ 4)
再 / 10
来实现掐头去尾。
上完整代码:
class Solution {
public:
bool isPalindrome(int x) {
if (x < 0) {
return false;
}
if( x < 10) {
return true;
}
int div = 1;
int x1 = x;
while(x1 >= 10) {
div *= 10;
x1 /= 10;
}
while (x > 0) {
int l = x / div;
int r = x % 10;
if (l != r) {
return false;
}
x = x % div / 10;
div /= 100;
}
return true;
}
};
这里我们考虑一种特殊情况,比如 x 是 100341,那么掐头去尾之后,x 变成了 34,而不是 0034,这会不会对我们的结果造成影响呢?
我们发现执行第二次循环的时候 div = 10000
,那么 34 / 10000 -> 0
,也就是说我们还是取到了正确的数字 0 而不是3 。这得益于我们保留了之前的 div 的值然后每次 / 100
,而不是每次都重新计算 x 的位数。
执行第三次循环的时候 x = 3, div = 100
,那么3 / 100 -> 0
,我们依然取得了正确的数字,也就是说我们上面的解法是正确的。
提交之后成功通过,运行时间 44 ms。
Solution2 优化
我们观察一下上面解法中获取 x 位数的部分:
int div = 1;
int x1 = x;
while(x1 >= 10) {
div *= 10;
x1 /= 10;
}
我们发现我们每次运算的时候都要把 div * 10
然后把 x1 / 10
。那为什么不把这两部分结合起来直接用 while(x / div >= 10)
来当循环条件呢?
class Solution {
public:
bool isPalindrome(int x) {
if (x < 0) {
return false;
}
if( x < 10) {
return true;
}
int div = 1;
while(x / div >= 10) {
div *= 10;
}
while (x > 0) {
int l = x / div;
int r = x % 10;
if (l != r) {
return false;
}
x = x % div / 10;
div /= 100;
}
return true;
}
};
再提交一下,这次的运行时间是 32 ms。
总结
虽然是一道看起来非常简单的题目,用转换成字符串的方式实现可能花不了几分钟的时间,但是不用字符串转换的方式要花点时间琢磨。这一题完整实现下来我自己也有新的收获,挺开心的。