这是LeetCode的第9个问题,刚的以解决,但解决问题的性能不是很好,速度比较慢。
先说一下自己的解题思路。
palindromes:回文数,即正反两个方向读数值相等的数字
负数不可以是回文。
因为不能使用额外空间,但很显然,4个字节的除了int还有float,所以只能用int。
首先应该提取每一位存入vector,之后依次比较,只要出现不同即返回FALSE。因为如果不借助数组之类的工具的话只能靠一个新的数字进行比较。但这个时候就会出现溢出问题,所以采用vector。
代码如下:
public boolean isPalindrome(int x) {
if(x<0)
return false;
int beishu=10,yushu=0,shang=1;
Vector<Integer> v=new Vector<Integer>();
while(shang!=0){
yushu=x%beishu;
v.add(yushu);
shang=(x-yushu)/beishu;
x=(x-yushu)/beishu;
}
int length=v.size();
for(int i=0;i<length/2;i++){
if(v.elementAt(i)!=v.elementAt(length-1-i))
return false;
}
return true;
}
查看大神的代码发现有一种很好的解法:
public boolean isPalindrome(int x) {
if (x<0 || (x!=0 && x%10==0)) return false;
int rev = 0;
while (x>rev){
rev = rev*10 + x%10;
x = x/10;
}
return (x==rev || x==rev/10);
}
这种解法的思路就是首先清除尽可能多的特殊情况:当为负数或者最后一位为0的时候肯定不是回文数,因为不可能第一位有1.
之后将这个数字分为两部分,前一部分和后一部分(后一部分是有rev进行反转之后得到的结果,先取余数,然后依次*10+余数)
之后直接比较两个数字是否相等,如果位数为奇数的时候,rev肯定要比x多一位,所以比较除中间一位之后的位数,或者说是rev的最后一位。
这种方法很棒,首先不用引入其他的数据结构,其次,完全不用担心溢出的问题。
另一种很好的解法:
public boolean isPalindrome(int x) {
if (x < 0) return false;
int p = x;
int q = 0;
while (p >= 10){
q *=10;
q += p%10;
p /=10;
}
return q == x / 10 && p == x % 10;
}
加快速度的做法:
public static boolean isPalindrome(int x) {
//optimizations
if(x<0) return false;
if(x<10) return true;
if(x%10==0) return false;
if(x<100&&x%11==0) return true;
if(x<1000&&((x/100)*10+x%10)%11==0) return true;
//actual logic
v=x%10;
x=x/10;
while(x-v>0)
{
v=v*10+x%10;
x/=10;
}
if(v>x){v/=10;}
return v==x?true:false;
}
这个方法的思想与第一个方法相同,但之前的准备工作可以过滤掉大量数据,所以会运行的特别快。