LeetCode | 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.

判断一个数字是否是回文数


题目解析:

首先要考察输入的可能的数据,x小于0,x等于0以及x大于0。我们可以自行决定x小于0是否需要判断回文。

思路一:

例如“132231”判断最高位和最低位是否相等,如果相等接着判断里面的数字,这样就需要通过除法(/)和求余(%)两个操作来判断。

求余好判断,对10取模,下一趟的时候先除以10再取模,得到次低位,但是对于最高位有什么办法?我们求出整数的位数m,第一次对10^m取模(设为t),下一次取模之前先减去t*10^m,就将最高位去掉了。

当然上面两个应该相互结合才能得到正确结果。代码如下:

class Solution {
public:
    bool isPalindrome(int x) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (x < 0)
            return false;
        if (x == 0)
            return true;
            
        int base = 1;
        while(x / base >= 10)
            base *= 10;
            
        while(x)
        {
            int leftDigit = x / base;
            int rightDigit = x % 10;
            if (leftDigit != rightDigit)
                return false;
            
            x -= base * leftDigit;
            base /= 100;
            x /= 10;
        }
        
        return true;
    }
};

注意:base为基数,应该除以100。这个过程和上面的分析过程有点不一样,上面分析是将数据x/10然后赋给x,但这里是将基数base改变。其实质是一样对


思路二:

对于回文问题,我们可以通过翻转来得到!将数n反转,从低位到高位输出,比如“34525”反转后为“52543”,然后判断两个数是否相等。其实这也用到了之前的题目:LeetCode | Reverse Integer 不过这样会面临同样一个问题:翻转后,可能会越界。(其实这个问题也能忽略,不越界的时候,不相等就是不相等。越界了的话,证明不是回文数,也可以通过越界后的数据是否与原数是否相等来判断)

代码如下:与我之前写的代码不一样,这个更简化一些

class Solution {
public:
    bool isPalindrome(int x) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if(x < 0) return false;
        
        long long target = x;
        //if(target < 0) target = -target; 
        long long reverse = 0;
        long long curNum = target;
        while(curNum != 0)
        {
            reverse = 10*reverse+curNum%10;
            curNum /= 10;
        }
        
        return reverse == target;
    }
};

这里其实就是将x低位依次取模,然后不断乘以10变高位与次低位相加。最后于元数据判断,是否相等。思路很简单。


思路三:对思路二的优化

我们考察一个数据是否为回文数,如果没限制用空间的话,我们可以转换成数组,然后利用之前判断最长回文字符串的方法来求解。但是这里限制不能用空间,那么我们就要想想其他办法。

我们可以写几个数据“345543”和“3578753”,还记得之前的移位题目:【程序员编程艺术】第一章:左旋转字符串 那里是将123abcd变成 abcd123。看着跟这个题目毫无关系,但可以借鉴里面的策略:先将整个序列全翻转(dcba321),再分别翻转两段序列(abcd123)。这样就得到了我们想要的。

同样,我们要判断回文字符串,我们也可以将数据拆分成两段,高位段和低位段,然后将低位段翻转,判断是否和高位段相等。

比如“345543”分解成“345”和“543”;“3578753”分解成“357”“753”(这里就要区别数据是奇数位还是偶数位)

代码如下:(这里我们将负数也考察,先将其转化成正数,然后判断是否为回文数)

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int PalindromeNumber(int n);
int ReverseInteger(int n);

int main(void)
{
    int n;

    while(scanf("%d",&n) == 1){
        int flag = PalindromeNumber(n);
        if(flag)
            printf("true\n");
        else
            printf("false\n");
    }

    return 0;
}

int PalindromeNumber(int n)
{
    unsigned int temp;
    int numhi,numlo;
    int pownum;

    if(n == 0)
        return 1;

    if(n < 0){  //将负数转化成正数判断
        temp = -n;
    }else
        temp = n;

    int Nbit = 0;

    while(n){
        ++Nbit;
        n /= 10;
    }

    if(Nbit % 2){
        Nbit = Nbit/2;
        pownum = (int)pow(10,Nbit);
        numlo = temp % pownum;
        numhi = temp / (pownum*10);
    }else{
        Nbit = Nbit/2;
        pownum = (int)pow(10,Nbit);
        numlo = temp % pownum;
        numhi = temp / pownum;
    }

    numlo = ReverseInteger(numlo);
    printf("numhi = %d,numlo = %d\n",numhi,numlo);
    if(numhi == numlo)
        return 1;
    return 0;
}

int ReverseInteger(int n)
{
    if(n == 0)
        return 0;
    unsigned int temp;
    if(n < 0)
        temp = -n;
    else
        temp = n;

    int result = 0,remainder;
    while(temp){
        remainder = temp % 10;
        result = result * 10 + remainder;
        temp /= 10;
    }

    return result;
}


点赞