leetcode.windliang.cc/ 第一时间发布html
判断是否是回文数,负数不是回文数。java
把 int 转成字符串,而后判断是不是回文串作就能够了,缺点是须要额外的空间存储字符串,固然题目也告诉了不能这样,因此 pass 。git
在第 7 道题咱们写了倒置 int 的算法,这里固然能够用到了,只须要判断倒置先后相不相等就能够了。算法
记不记得,当倒置后的数字超出 int 的范围时,咱们返回的是 0 ,那么它必定不等于原数,此时必定返回 false 了,这正不正确呢?spa
咱们只需证实,若是倒置后超出 int 的范围,那么它必定不是回文数字就行了。code
反证法,咱们假设存在这么一个数,倒置后是超出 int 范围的,而且它是回文数字。cdn
int 最大为 2147483647 ,htm
让咱们来讨论这个数多是多少。blog
有没有多是最高位大于 2 致使的溢出,好比最高位是 3 ,由于是回文串,因此最低位是 3 ,这就将致使转置前最高位也会是 3 ,因此不多是这种状况。leetcode
有没有多是第 2 高位大于 1 致使的溢出,此时保持最高位不变,假如第 2 高位是 2,由于是回文串,因此个位是 2,十位是 2 ,一样的会致使倒置前超出了 int 的最大值,因此也不多是这种状况。
同理,第 3 高位,第 4,第 5,直线左边的都是上述的状况,因此不多是前边的位数过大。
为了保证这个数是溢出的,前边 5 位必须固定不变了,由于它是回文串,因此直线后的灰色数字就必定是 4 ,而此时无论后边的数字取多少,都不多是溢出的了。
综上,不存在这样一个数,因此能够安心的写代码了。
public int reverse(int x) {
int rev = 0;
while (x != 0) {
int pop = x % 10;
x /= 10;
if (rev > Integer.MAX_VALUE / 10)
return 0;
if (rev < Integer.MIN_VALUE / 10)
return 0;
rev = rev * 10 + pop;
}
return rev;
}
public boolean isPalindrome(int x) {
if (x < 0) {
return false;
}
int rev = reverse(x);
return x == rev;
}
复制代码
时间复杂度:和求转置同样,x 有多少位,就循环多少次,因此是 O(log(x)) 。
空间复杂度:O(1)。
其实,咱们只须要将右半部分倒置而后和左半部比较就能够了。好比 1221 ,把 21 转置和 12 比较就好了。
public boolean isPalindrome(int x) {
if (x < 0) {
return false;
}
int digit = (int) (Math.log(x) / Math.log(10) + 1); //总位数
int revert = 0;
int pop = 0;
//倒置右半部分
for (int i = 0; i < digit / 2; i++) {
pop = x % 10;
revert = revert * 10 + pop;
x /= 10;
}
if (digit % 2 == 0 && x == revert) {
return true;
}
//奇数状况 x 除以 10 去除 1 位
if (digit % 2 != 0 && x / 10 == revert) {
return true;
}
return false;
}
复制代码
时间复杂度:循环 x 的总位数的一半次,因此时间复杂度依旧是 O(log(x))。
空间复杂度:O(1),常数个变量。
这几天都比较简单,加油加油加油!。