0001 回文数

回文数

每天一道算法题,今天是第一天,目标是写到第一千天,希望我可以做到

编号:0001

本文使用的编程语言c++,算法题来源leetcode

题目描述

判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。(待判断的整数在int范围内)

示例输入输出

  • 示例1:

    输入:121

    输出:true

  • 示例2:

    输入:-121

    输出:false

    解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。

  • 示例3:

    输入:10

    输出:false

    解释:从右向左读, 为 01 。因此它不是一个回文数。

题解

转换为字符串

int类型的数字转换成char类型的数组,然后第一位和最后一位对比,第二位和倒数第二位对比,依次类推。

因为负数一定不是回文数,因此先对负数进行判断排除。

class Solution {
public:
    bool isPalindrome(int x) {
        if(x < 0 || (x % 10 == 0 && x != 0))   //负数和尾数为0的非零数不是回文数
            return false;
        char temp[10];         //定义一个数组,存放int
        int i = 0;
        while (x != 0)         //遍历数字x的每一位,把它放在数组中
        {
            temp[i++] = x % 10 + '0';
            x = x / 10;
        }
        int l = i;
        for (i = 0; i < l / 2; i++)       //数组temp中前后进行比较,若中间任何一次比较不等,返回false
            if (temp[i] != temp[l - 1 - i])
                return false;
        return true;
    }
};
不用转换为字符串
完整比较

如果是12321这个数字,可以通过x/10000得到最高位,x%10得到最低位,然后进行比较;在通过(x%10000)/10得到232这个新的要比较的数,进行上述操作;一直到x小于10为止。

同样的负数一定错误,因此先对负数进行判断。

class Solution {
public:
	bool isPalindrome(int x){
        if(x < 0 || (x % 10 == 0 && x != 0))   //负数和尾数为0的非零数不是回文数
            return false;
        int div = 1;
        while(x / div >= 10){div *=10;}  //找到要求的最高位被除数div
        while(x > 0)
        {
        	if(x / div != x % 10)       //比较当前最低位和最高位是否相同
        		return false;
        	x = (x % div) / 10;         //生成新的比较数
        	div /= 100;                 //注意整个数字少了2位,因此div/100
        }
        return true;
    }    
};

完整比较除了像上面一样,本质上还是字符的角度,进行从前到后的一一对应,还可以生成一个逆转的数字,也就是说新数字的最高位是原数字的最低位,如果新生成的数字和原数字相同,那么显然原数字就为回文数。

这里面需要注意逆转数可能超过int的表示范围,因此要注意判断溢出数,又因为溢出的时候显然不是回文数,直接返回false就可以

class Solution {
public:
	bool isPalindrome(int x){
        if(x < 0 || (x % 10 == 0 && x != 0))   //负数和尾数为0的非零数不是回文数
        	return false;
        int reverse = 0, temp = x;   //reverse存储逆转后的数字,temp表示原来的数
        while(temp > 0)
        {
        	if (reverse > INT_MAX / 10) //判断是否会溢出,如果reverse溢出,那么显然原数字不可能是回文数
        		return false;
        	reverse = reverse * 10 + temp % 10;  //把temp的最低位变成reverse的较高位
        	temp /= 10;
        }
        return (reverse	== x);       //直接判断reverse和原数字是否一样即可
    }    
};
不完整比较

不完整算法的基本思路和完整比较的第二种比较类似,但是为了回避掉逆转数可能溢出的问题,我们可以只将原数字的一半进行逆转。例如说对1221进行判断,我们只要将其一半进行逆转,也就是21逆转为12,与原数字前一半相同,是回文数。

这里面的关键是如何判断我们已经逆转了一半,可以简单通过reverse >= x作为判断标准

class Solution {
public:
	bool isPalindrome(int x){
        if(x < 0 || (x % 10 == 0 && x != 0))   //负数和尾数为0的非零数不是回文数
        	return false;
        int reverse = 0;
        while(x > reverse)                    //判断仅逆转一半
        {
        	reverse = reverse * 10 + x % 10;
        	x /= 10;
        }
        //当数字长度为奇数时,我们可以通过 reverse/10 去除处于中位的数字。
        return (reverse	== x || reverse / 10 == x);
    }    
};

参考题解:

[1] https://leetcode-cn.com/problems/palindrome-number/solution/hui-wen-shu-by-leetcode/

[2] https://leetcode-cn.com/problems/palindrome-number/solution/dong-hua-hui-wen-shu-de-san-chong-jie-fa-fa-jie-ch/

[3] https://leetcode-cn.com/problems/palindrome-number/solution/hua-jie-suan-fa-9-hui-wen-shu-by-guanpengchn/

[4] https://leetcode-cn.com/problems/palindrome-number/solution/c-zhi-yong-yi-ge-e-wai-intbian-liang-6xing-chao-ji/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值