@Leetcode回文数
回文一直是很诗意的艺术形式,我们可以看到诸如 “雪映梅花梅映雪,莺宜柳絮柳宜莺” 这样的回文对联,在算法分析中,回文数的写法同样是极富有诗意的。
先看题干:
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。能不将整数转为字符串来解决这个问题吗?(进阶要求)
示例如下:
输入: 121
输出: true
输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数
输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。
从示例我们可以看到,能完成这个回文任务的只有正数,因为负号不能回文,并且所有模10为0的数也都会被排除在外,因为并不能找到0开头的数字。这是本题示例上传达的基本信息。
那么接下来就是决定是否将整数转为字符串了!根据这个选择的不同,本题的接替思路有两种版本,我们先来看看大家所熟知的转字符串的方法:
class Solution {
public:
bool isPalindrome(int x) {
int k=1;//从第一个位置开始记录(此处可以使用第0个)
int flag=1;
char m[105];
char n[105];
if(x==0)
return true;
if(x<0||x%10==0)
return false;
while(x)
{
m[k]=x%10+'0';//转化为字符型
k++;
x=x/10;
}
m[k]='\0';
k--;
int j=1;
while(k>=1)
{
n[j]=m[k];
k--;
j++;
}
n[j]='\0';
for(int i=1;i<=(strlen(n)-1)/2;i++)//偶数一半判断,奇数一半少一个中间
{
if(n[i]!=m[i])
{
flag=0;
break;
}
}
if(flag==1)
return true;
else if(flag==0)
return false;
return 0;
}
};
本人自忖代码能力不够,为了展现思路,亲自动手写了一份简单易懂、老少皆宜、啰里啰唆、混水摸鱼、开门见山、大刀阔斧、天马行空、奇奇怪怪、红橙作伴的代码。虽说如此,但这份代码把所有的步骤全部分开了,也就更容易明白这个方法需要使用那些判断和各类条件。
思路很明晰,首先通过+’\0’将数字挨个转换成字符,存入之后使用两个不同的char数组来进行比较,此处只要比较一半就够了,只要有不同之处,就证明不是回文数。负数、10的整数倍和0的判断在最前面,注意,0是回文数,所以我就意拉出来判断了。
需要注意的细节是数组下标的问题,0开始和1开始时对应的判断和循环条件是完全不同的,而且修改的小地方也有很多,需须细推敲得出正确的比较方案。
那么进阶要求中的不使用字符串的转化应该怎么做呢?我们来看下一种版本的代码:
class Solution {
public:
bool isPalindrome(int x) {
int m=x;
long com=0;
if(x==0)
return true;
if(x<0||x%10==0)
return false;
while(x)
{
com=com*10+x%10;
x=x/10;
}
if(m==com)
return true;
else
return false;
}
};
显然不用转化成字符串的方法思路更为简单,就是在《整数反转》这题之上加了一个判断的步骤,即可完成对回文数的判断。
关于整数反转的算法与分析,可以参考我的博客
(https://blog.youkuaiyun.com/Maple_PI/article/details/94969384 )
在其中有对整数反转的分析。需要注意的是上一版本种的三个特殊判断点在这一版本种任然适用,且为了避免溢出,com仍然需要使用长整型。