LeetCode 9. Palindrome Number

Determine whether an integer is a palindrome. Do this without extra space.

click to show spoilers.

Some hints:

Could negative integers be palindromes? (ie, -1)

If you are thinking of converting the integer to string, note the restriction of using extra space.

You could also try reversing an integer. However, if you have solved the problem "Reverse Integer", you know that the reversed integer might overflow. How would you handle such case?

There is a more generic way of solving this problem.


【题目分析】

判断一个int型整数是否是回文数。需要注意的有以下几点:

1. 负数是回文数吗?

2. 不允许使用额外的存储空间,即不可以把整数转换为字符串。

3. 如果采用先把整数翻转再比较它与原值是否相同的方法,考虑如何解决翻转后可能的overflow问题。


【思路】

1. 负数不是回文数,-121和121-是不同的。

2. 不把整数转换为其他存储形式。

3. 不使用对整数进行翻转的方法。

考虑如果不是判断一个整数,而是判断一个字符串我们会怎么办?

首先从头部取一个字符,再从尾部取一个字符,判断他们是否相同,逐渐向中心靠近。对整数我们也可以使用类似的方法,先求出整数的长度,然后计算尾部的数和头部的数,依次比较,逐渐向中心靠近。


【java代码1】

 1 public class Solution {
 2     public boolean isPalindrome(int x) {
 3         if(x < 0) return false;
 4         int len = 1, num1 = x, num2 = x, y = 1;
 5         
 6         while(x / 10 != 0){
 7             x = x / 10;
 8             y = y * 10;
 9             len ++;
10         }
11         
12         for(int i = 1; i <= len / 2; i++){
13             int a = num1 % 10;
14             int b = num2 / y;
15             if(a != b) return false;
16             num1 = num1 / 10;
17             num2 = num2 % y;
18             y = y / 10;
19         }
20         
21         return true;
22     }
23 }

对代码进行优化如下:

【Java代码2】

 1 public class Solution {
 2     public boolean isPalindrome(int x) {
 3         if(x < 0) return false;
 4         int div = 1;
 5         while(x / div >= 10){
 6             div *= 10;
 7         }
 8         while(x != 0){
 9             int l = x % 10;
10             int r = x / div;
11             if(l != r) return false;
12             x = (x % div) / 10;
13             div /= 100;
14         }
15         
16         return true;
17     }
18 }

大神的写法果然简洁了好多!一种更简单的写法如下:

 1 public class Solution {
 2     public boolean isPalindrome(int x) {
 3         if (x<0 || (x!=0 && x%10==0)) return false;
 4         int rev = 0;
 5         while (x>rev){
 6             rev = rev*10 + x%10;
 7             x = x/10;
 8         }
 9         return (x==rev || x==rev/10);
10     }
11 }

上面的代码先把不可能是回文数的所有数排除掉(负数,结尾数字是0的数);

接着计算数的前半部分和后半部分,比较他们是否相同。

上面这三种方法的时间复杂度比较如下:

原文地址:https://www.cnblogs.com/liujinhong/p/5972375.html