【LeetCode】9,回文数。 难度等级:简单。巧妙解法很多,值得推敲。

LeetCode 第9题,回文数;难度等级:简单

一、题目

在这里插入图片描述

二、我的解答:逐个判断对应位置的首末数字是否相同

我的第一想法是直接处理数字,逐个判断对应位置的首末数字是否相同。导致代码写的比较复杂,速度也不快。代码如下:

class Solution {
    
    
public:
    bool isPalindrome(int x) {
    
    
        if(x<0)
            return false;
        else if(x>=0 && x<10)
            return true;
        else{
    
    
            // 先计算 x 的长度 length
            int length=1;
            while(x/int(pow(10,length))>=10){
    
    
                length++;
            }
            length++;

            //逐个判断对应位置的首末数字是否相同,如 12345 中的 1-5和2-4
            for(int i=1;i!=length/2+1;i++){
    
    
                int end=(x % int(pow(10,i)))/int(pow(10,i-1));
                int begin=(x/int(pow(10,length-i)))%10;
                if(begin!=end)
                	return false;
            }
            return true;
        }
    }
};

执行结果:

执行用时:20 ms, 在所有 C++ 提交中击败了 17.33% 的用户
内存消耗:6 MB, 在所有 C++ 提交中击败了 11.80% 的用户

三、其他解答

3.1 将数字x转为字符串进行处理

逐个位数比较数字非常麻烦,但处理字符串是很简单的,因为只需要下标操作即可。因此可以将数字x转为字符串进行处理,代码如下(我自己写的,官方代码只有C++):

class Solution {
    
    
public:
    bool isPalindrome(int x) {
    
    
        if(x < 0 || (x % 10 == 0 && x != 0))
            return false;

        // 将x转为字符串
        string str_x=to_string(x);
        int length=str_x.size();
        for(int i=0;i!=length/2;i++)
            if(str_x[i]!=str_x[length-i-1])
                return false;
        return true;
    }
};

执行结果:

执行用时: 4 ms, 在所有 C++ 提交中击败了 95.08% 的用户
内存消耗: 5.8 MB, 在所有 C++ 提交中击败了 33.42% 的用户

知识点:

(1) string s = to_string(i)用于将数字常量转换为字符串,但需要包含头文件 #include<string>
(2) str.size()和str.length()都可以获取字符串长度

3.2 反转一半数字进行比较

如何判断 x = 1234是不是回文数呢?除了依次判断数对 (1,4) 和 (2,3) 是否相等,还有一种直观的方法是先获得 x 的逆序数 x_reverse = 4321,然后通过 if(x == x_reverse) 来判断 x 是否为回文数。但这样容易造成数值上溢,如:

最大整数为 intMax = 2^31^-1 = 2147483647,而 intMax _reverse = 7463847412 > intMax 

intMax 反转后就导致了数值上溢,尽管可以使用 long long等数据类型来解决该问题,但这种解决方法显然是不完美的。

实际上,只需要反转一半数字就可以判断回文数。

比如获得 x = 1234 的一半反转数字 x_reverse = 43,然后获得前一半的数字 x_begin = 12,通过if(x_begin == x_reverse) 来判断 x 是否为回文数。但需要特别注意奇数和偶数的情况下,获得的x_begin 是不同的。

代码:

class Solution {
    
    
public:
    bool isPalindrome(int x) {
    
    
        if(x < 0 || (x % 10 == 0 && x != 0))
            return false;
        int x_reverse=0;
        while(x_reverse < x){
    
    
            x_reverse = x_reverse*10+x%10;
            x/=10;
        }
        // 当数字长度为奇数时,我们可以通过 x_reverse/10 去除处于中位的数字。
        // 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,x_reverse = 123,
        // 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
        return x==x_reverse || x==x_reverse/10;
    }
};

知识点:

return x==x_reverse || x==x_reverse/10;  这一步非常巧妙

猜你喜欢

转载自blog.csdn.net/qq_43799400/article/details/130517654