@LeetCode回文数--Palindrome Number[C++]
问题描述
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右到左)读都是一样的整数。
示例1:
输入: 121
输出: true
示例2:
输入: -121
输出: false
解释: 从左向右读,为 -121。从右向左读,为 121-。因此它不是一个回文数。
示例3:
输入: 10
输出: false
解释: 从右向左读,为 01。因此它不是一个回文数。
解决方法及复杂度分析
思路
首先,很容易想到将数字本身反转,然后将反转后的数字与原始数字进行比较。如果它们是相同的,那么这个数字就是回文。但是,如果反转后的数字大于 INT_MAX,我们将遇到整数溢出问题。
为了避免数字反转可能导致的溢出问题,我们只反转 int 数字的一半,如果该数字是回文,其后半部分反转后应该与原始数字的前半部分相同。
例如,输入 1221,可以将数字 “1221” 的后半部分从 “21” 反转为 “12”,并将其与前半部分 “12” 进行比较,因为二者相同,我们得知数字 1221 是回文。
算法
首先,我们应该处理一些临界情况。所有负数都不可能是回文,例如:-123 不是回文,因为 - 不等于 3。所以所有负数均可返回 false。
现在,考虑如何反转后半部分的数字。对于数字 1221,如果执行 1221 % 10
,将得到最后一位数字 1,要得到倒数第二位数字,可以先通过除以 10 把最后一位数字从 1221 中移除,
1221
/
10
=
122
1221/10=122
1221/10=122,再求出上一步结果除以10的余数, 122 % 10 = 2
,就可以得到倒数第二位数字。如果我们把最后一位数字乘以10,再加上倒数第二位数字,
1
∗
10
+
2
=
12
1 * 10 + 2 = 12
1∗10+2=12,就得到了我们想要的反转后的数字。如果继续这个过程,将得到更多位数的反转数字。
那么判断反转数字的位数已经达到原始数字位数的一半?
我们将原始数字除以 10,然后给反转后的数字乘上 10,所以,当原始数字小于反转后的数字时,就意味着我们已经处理了一半位数的数字。
复杂度分析
- 时间复杂度: O ( l o g 10 ( n ) ) O(log_{10}(n)) O(log10(n)),对于每次迭代,我们会将输入除以10,因此时间复杂度为 O ( l o g 10 ( n ) ) O(log_{10}(n)) O(log10(n))。
- 空间复杂度: O ( 1 ) O(1) O(1)。
程序实现
class Solution {
public:
bool isPalindrome(int x) {
if(x < 0 || (!(x % 10) && x)) return false;
int revertedNumber = 0;
while(x > revertedNumber) {
revertedNumber = revertedNumber * 10 + x % 10;
x /= 10;
}
return x == revertedNumber || x == revertedNumber / 10;
}
};
@山东·威海 2019.02.02