9. 回文数
- 给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
- 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
- 例如,121 是回文,而 123 不是。
方法一:将整数转化为字符串
利用stringstream
进行数字和字符串的转换
#include<sstream>
int main(){
double numA = 123.32;
string strA;
stringstream NumToStr; //定义流ss
string strB = "1649";
double numB;
stringstream StrToNum; //定义流ss
//借助 流 来进行数字和字符串的转换
NumToStr << numA; //将数字numA 转化成流NumToStr
NumToStr >> strA; //将流NumToStr转化成字符串
StrToNum << strB;
StrToNum >> numB;
return 0;
}
所以,该题目的求解代码如下:
bool isPalindrome(int x) {
if (x < 0) return false;
stringstream ss;
string str = "";
ss << x;
ss >> str;
//获取字符串的长度
int strSize = size(str);
//从字符串的两头开始遍历
for (int i = 0,j=strSize-1; i < j; i++,j--)
{
if (str[i] != str[j]) return false;
}
return true;
}
方法二:反转一半数字
将数字本身反转,然后将反转后的数字与原始数字进行比较,如果它们是相同的,那么这个数字就是回文。
但是,如果反转后的数字大于$ \text{int.MAX}$,我们将遇到整数溢出问题。为了避免数字反转可能导致的溢出问题,可以考虑反转
int
\text{int}
int 数字的一半,如果该数字是回文,其后半部分反转后应该与原始数字的前半部分相同。
反转思路
将\text{int}数字进行模10可以得到最后一位数字,将\text{int}除以10后可以把最后一位数字移除,然后进行模10操作可得到倒数第二位数字,重复该过程可以得到每一位上的数字。
将最后一位数字*10,然后加上倒数第二位数字,即可得到\text{int}数字后两位的反转数字,继续这个过程,可以得到更多位的反转数字。
如何判断反转数字的位数达到了原始数字的一半?
由于整个过程我们不断将原始数字除以 10
,然后给反转后的数字乘上 10
,所以,当原始数字小于或等于反转后的数字时,就意味着已经处理了一半位数的数字了。
过程示意图
代码实现
bool isPalindrome(int x) {
// 当 x < 0 时,x 不是回文数,如-121。
// 除0外,第一位数字不能是0,所以最后一位的数字是0的数,也不是回文数,如10
if (x < 0 || (x % 10 == 0 && x != 0)) {
return false;
}
//revertedNumber获取数字后半部分的反转数字
int revertedNumber = 0;
while (x > revertedNumber) {
revertedNumber = revertedNumber * 10 + x % 10;
x /= 10;
}
return x == revertedNumber || x == revertedNumber / 10;
}