#9 Palindrome Number

本文介绍了一种在不使用额外空间的情况下判断整数是否为回文的方法。通过反转整数并检查反转前后是否相等来实现,同时考虑了数字溢出的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目内容描述:

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

一般判断回文数字,会把它先转换成字符串然后用头尾两个指针扫描字符串判断即可。但是题目要求不能申请多余的空间,也就是不能转换成字符串,这个难度就上来了,字符操作变成了数字操作,需要更多的技巧。

首先按照回文的定义,负数由于负号的存在肯定不是回文数字
其次只有一个数位的数字即0~9一定是回文数字
最后对于一般的数字我们直接将数字翻转,然后比较翻转前后的两个数字是否大小相等即可

针对数字的翻转用的算法比较巧妙:

int reverseNum = 0;
while(num!=0){
    reverseNum = reverseNum*10 + num%10;
    num /= 10;
}

拆分数位时,一般会不断模10取值,这个时候取出的数字是倒序的,翻转时相应数位的权值会颠倒恰好就可以递归乘10,能够得到翻转的结果。
但是
到这里还没有完,一旦牵涉到数字运算就必须考虑到数字的溢出问题,如果数据溢出,还能不能够判断这个回文数字呢?假如一个数字翻转之后的数字溢出了,那肯定不是这个数字原来的值了,这个时候不就没办法判断了吗?
仔细推理一下
输入的变量值是一个正常的int型整数,-2147483648~2147483647的取值范围,如果它真的溢出了说明输入的数值是一个十位数,然后末尾的最后一个数字大于2,在这种情况下首尾数位的数字不相等,肯定不是回文数字,所以一旦溢出,一定不是回文数字。
判断溢出的办法就比较简单了,如果在一个增加数值的情况下,这个数字反而比原来的数字还小,那就证明发生了溢出。

具体题解代码如下:

class Solution{
    public:
        bool isPalindrome(int x){
            if(x<0){
                return false;
            }else{
                if(x<=9){
                    return true;
                }else{
                    int reverse_X=0,temp=x,Judge;
                    while(temp!=0){
                        Judge = reverse_X;
                        reverse_X=reverse_X*10+temp%10;
                        if(reverse_X<Judge){
                            return false;
                        }
                        temp/=10;
                    }
                    if(reverse_X==x)
                        return true;
                    else
                        return false;
                }
            }
        }
};

这个题在最开始写时,没有好好考虑溢出与判断回文之间的关系,只是想要在一个数字上实现相当于字符串的操作,不断地去掉提取出输入数字的首尾数位进行比较,然后去掉头尾数字,再进行接下来的比较。
这个时候问题明显变得更复杂了,去掉尾部数字除10即可,没有问题,但是在去掉头部数字时有了问题,如果第二个数位的数字为0,去掉头部数字之后第二个数位就会消失。这个时候就出现了数字和字符串的不同,这个时候证明之前的想法肯定是不对的,要推倒重来。

不能死钻牛角尖,目的是解决问题,不是修补错思路上的漏洞。

然后问题就来到了下一个阶段,既然在数字上进行原地操作很困难,就放弃对数字的调整。把头尾数位数字看做是指针,问题就变成了如何取出指针对应数位的数字,这个时候就可以用到上面的思考,取出末尾数位的数字是最可靠的,那就尾部截断输入的数字,使要求的数位在末尾,随机模10 即可。

另一种解法代码如下:

class Solution{
    public:
        bool isPalindrome(int x) {
            //负数 一定不是回文数字 这个时候把它看成字符串 
            if(x<0){
                return false;
            }
            //i j 分别指向数字头尾的指针  
            int i,j,top_digit,bottom_digit,temp,digitSum=0;
            temp = x;
            while(temp!=0)
            {
                digitSum++;
                temp/=10;
            }
            i = digitSum-1,j=0;
            while(i>j)
            {
                top_digit=(int)(x/pow(10,i));
                top_digit=top_digit%10;
                bottom_digit=(int)(x/pow(10,j));
                bottom_digit=bottom_digit%10;
                cout<<"top_digit = "<<top_digit<<"  "<<"bottom_digit = "<<bottom_digit<<endl;
                if(top_digit!=bottom_digit)
                    return false;
                i--;
                j++;
            }
            //错误写法 针对数字的原地操作 思路错了 
            /*while(flag){
                top_digit = x/pow(10,i);
                bottom_digit  = x%10;
                if(top_digit!=bottom_digit){
                    return false;
                }
                x/=10;
                i--;
                x = x-(int)((pow(10,i))*top_digit);
                if(x>=0&&x<=9)
                    flag=0;
            }*/

            return true;
        }
};

总的来说,第一种解法是比较优雅,充分利用了数字的特性,第二种解法是换了个方式模拟一个字符数列,算是取巧了。这道题本身没有太高的立意,只是一般的考验逻辑的题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值