问题描述
问题分析
分析题目,这是一个水题。最开始想的是将数字转为字符串来做,直接使用首尾游标遍历一半元素即可得出答案,特别方便。
- 时间复杂度:O( n ),其中 n 是数字的长度。
- 空间复杂度:O( 1 )
Java代码
class Solution {
public boolean isPalindrome(int x) {
if ( x < 0 ){
return false;
}
String str = String.valueOf(x);
int start = 0;
int end = str.length()-1;
while (start < end){
if (str.charAt(start) != str.charAt(end)){return false;}
start++;
end--;
}
return true;
}
}
结果分析
以上代码的执行结果:
执行时间 | 内存消耗 |
---|---|
53ms | 37.3MB |
看了题目中的进阶要求,我尝试不使用字符串来优化该算法的时间复杂度。
对于数字,可以这样考虑:用%10得到最后一位,然后使用/10去除原数字的最后一位,依次迭代,就能将原数字逆置。但是这样又会产生逆置后的数字溢出的情况。
其实稍微想一下回文的定义就知道,我们只需要逆置一半的数字就够了,直接和原数字的剩余部分比较是否相等。那么问题就变成了,我们怎么知道已经迭代到原来数字的一半了。
观察得知,原始数字除以 10去除了最后一位,长度变短了一位;而反转数字每次迭代都增加了一位。
比如输入1221,第一次迭代:原始数字为122,反转数字为1;
第二次迭代:原始数字为12,反转数字为12
比如输入12321,第一次迭代:原始数字为1232,反转数字为1;
第二次迭代:原始数字为123,反转数字为12
第三次迭代:原始数字为12,反转数字为123
所以,当原始数字小于或者等于反转后的数字时,就意味着我们已经处理了一半位数的数字。
优化后的代码如下:
class Solution {
public boolean isPalindrome(int x) {
if (x < 0 || (x%10==0 && x!=0)){return false;}
int key = 0;
while (x > key){
key = key*10 + x%10;
x = x/10;
}
return key == x || key/10 == x;
}
}
- 时间复杂度:O( log10 (n) ),其中 n 是数字的长度。
- 空间复杂度:O( 1 )
执行时间 | 内存消耗 |
---|---|
49ms | 37MB |