题目描述
判断一个整数是否是回文数。不能使用辅助空间(即要求空间复杂度为O(1))。
负整数可以是回文数吗?(例如 -1,不可以,所有的负数都不是回文数)
如果你打算把整数转为字符串,请注意不允许使用辅助空间的限制。
你也可以考虑将数字颠倒。但是如果你已经解决了 “颠倒整数” 问题的话,就会注意到颠倒整数时可能会发生溢出。你怎么来解决这个问题呢?
解题思路分析和实现方法
方法一:
第一反应就是将整数转换为字符串,然后检查字符串是否是回文。但创建字符串需要O(n)的(非常量)空间,这与题目的要求是不符合的。
第二个想法是,将整数本身逆序,然后将逆序后的整数和原来的整数进行比较。如果它们相同,那么一定是回文数。但是,需要注意的是,逆序后的数字可能>int.Max。这会导致溢出。
为了避免产生溢出问题,我们可以只逆序整数的一半。回文数的后半部分的逆序应该和回文数的前半部分相同。
举个例子,如果输入的是“1221”,我们可以将“1221”的后半部分从“21”逆序为“12”,并与“1221”的前半部分进行比较。
如果相同,那么就是一个回文数。
对于整数“1221”,通过“1221%10”,我们就可以得到最后一位“1”。可以把“1221/10 =122”,再“122%10”,我们就可以得到倒数第二位了。
重复这样的过程,直到这个整数的中间位置。
然后,通过“1*10+2=12”就能得到整数后半部分的逆序了。
现在问题的关键是,我们如何知道,我们已经到了这个整数的中间位置了。
当逆序后的数的值大于原来的值的时候,就到了这个整数的中间位置了。
class Solution {
public boolean isPalindrome(int x) {
//1.所有的负数不是回文数
//2.如果这个整数的最后一位是0,那么只有这个数是0的时候才是回文数。如果不是0,那么就不是回文数
if(x < 0 || (x % 10 == 0 && x != 0)) {
return false;
}
int revertedNumber = 0;
while(x > revertedNumber) {
revertedNumber = revertedNumber * 10 + x % 10;
x /= 10; //注意这个过程
}
return x == revertedNumber || x == revertedNumber/10;
}
}
时间和空间复杂度分析
时间复杂度为:O(log N)
空间复杂度为:O(1)