1.题目描述
给你一个整数 x
,如果 x
是一个回文整数,返回 true
;否则,返回 false
。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
• 例如,121
是回文数,而 123
不是。
2.解法1(个人角度)——逐位分割,折半对比
看到题目之后,从数的角度考虑,回文数具有低位与高位相等的特点。
(1)建立一个整型数组,用来存储分割之后的数据
(2)进行逐位分割,存储在数组中
(3)折半对比,只需要比较一半的元素即可,判断是否为回文数
具体解法:
由题意知,负数必定不是回文数
0~9必定是回文数
其余的数,将其一一分解,放入数组中
这里采用了“投机取巧”的方法,int型的数据最多只有10位数,事先建立了一个能够包含10个元素数组
逐位分割之后,折中对比,首与尾相比,这里会出现一个易错点:如果两位数,下标则为1,除以2之后,则为0,就不会进行对比,对于此种情况,需进行判断,便可避免
代码实现:
bool isPalindrome(int x)
{
//情况1:负数
if(x < 0)
{
return false;
}
//情况2:个位数
else if((x >= 0) && (x < 10))
{
return true;
}
//情况3:大于9的整数
else
{
int i = 0,j = 0,k = 0,a[10] = {0};
//进行逐位拆分
while(x / 10)
{
a[i] = x % 10;
x /= 10;
i++;
if(x < 10)
{
a[i] = x;
}
}
j = i;
k = j / 2;
//两位数,则最大下标数为1,除以2后为0
if(0 == k)
{
k++;
}
//进行折半对比
for(i = 0;i <= k;i++)
{
if(a[i] != a[j-i])
{
return false;
}
}
}
return true;
}
3.解法2——反转一半数字比较
当然,题解中反转一半数字的方法也非常巧妙。
(1)负数和个位为0且不为0的数(因为最高位不可能为0),均不是回文数
(2)反转一半数字,利用取余每次得到最低位数字,每次除以10,将最低位舍弃
重点来了,那怎么判断是否数字已经反转了一半?
由于新数字在不断乘以10变大,原始数字不断除以10变小,当原始数字小于等于新数字时,说明就已经反转过半
说到这里,有的小伙伴可能在想,这样的算法可以站的住脚嘛?
比如,具有偶数位数的高位总比低位大,例如:654321
按照上述算法,原始数字:456,新数字:123,已经反转过半,但还是没有达到跳出循环的要求,最后一次循环,原始数字:65,新数字:1234
这里可能就会产生疑问,虽然上述示例不是回文数,返回值确实达到预期值,但是回文数可不可能出现错判呢?
事实并不会出现上述假设,对于回文数而言,偶数位数,反转一半后,其新数字与变换的原始数字必定相同;奇数位数,反转一半后,其新数字必定大于变换的原始数字
代码实现:
bool isPalindrome(int x)
{
//负数和个位数为0且不为0的数,最高位数不可能为0
if((x < 0) || ((x > 0) && (x % 10 == 0)))
{
return false;
}
//个位数
else if((x >= 0) && (x < 10))
{
return true;
}
//大于9且个位不为0的整数
else
{
int temp = 0;
while(x > temp)
{
temp = temp*10 + x %10;
x /= 10;
}
if((x == temp) || (x == (temp /10)))
{
return true;
}
else
{
return false;
}
}
}
4.解法3——将数据转化为字符串,折半比较
此外,还可以采用转化字符串的方法,与本人解法类似,利用sprintf()函数,将整数转化为字符串,存储在字符数组中,用转化字符的方法代替逐位分割,后续步骤相同,进行折中对比,判断是否为回文数
int sprintf( char *buffer, const char *format [, argument] ... );
函数功能:把一个格式化的数据转化为字符串
第一个参数:指向写入字符串的数组,其他参数与printf( )函数相同
sprintf()函数,其更加具有实用性,具体还需在网上查阅相关资料
C代码代码实现:
bool isPalindrome(int x)
{
char str[11] = {0};
//将整型转化为字符串
sprintf(str,"%d",x);
int len = strlen(str);
int i = 0;
for(i = 0;i <(len / 2);i++)
{
if(str[i] != str[len-1-i])
{
return false;
}
else
{
return true;
}
}
}
5.总结
上述三种解法,本质都是将整数折半进行对比,但前面的过程略有不同,正所谓“各花各有各花香”,各自有各自的优势,其中实现的细节,值得大家去思考,去体会。
部分解题思路参考力扣题解以及评论区中的大佬。 当然,如果这篇文章对你有所帮助或者有一种耳目一新的感觉,还请大家多支持支持,点点赞。