【被OJ毒打的第三天】LeetCode_简单_9.回文数
题干:
判断一个整数是否是回文数。回文数是指正序和倒序都是一样的整数。
提示:
你能不将数字转化为字符串做吗?
输入:
121
-121
10
输出:
true
false
false
1.我的做法
执行用时:28ms,11.5MB
思想:(最开始想要借用整数翻转的代码,先将整数翻转后再做相等比较,结果发现用例中有会造成溢出的大数,不得已放弃了这个偷懒的想法)先使用整数翻转中用到的方法将每一位数字保存在一个 vector<int> 里,在遍历前半部分,检验相反位置的数字是否与其相同
实现:首先由题意可知,负数全部为非回文数;然后发现,输入为 0 时 vector 为空,为了防止空指针报错,需要将 0 作为一种单独情况处理;之后的算法没有什么新的东西,照着思路实现即可
bool isPalindrome(int x) {
if (x < 0) {
return false;
}
if (x == 0) {
return true;
}
vector<int> arr;
while(x) {
arr.push_back(x % 10);
x /= 10;
}
int s = arr.size();
bool res = true;
for (auto i = 0; i <= s / 2; i++) {
res = res && (arr[i] == arr[s-i-1]);
}
return res;
}
改良:回文数只要有一对位置检测错误就可以直接返回 false,所以 res 和 && 运算是不必要的
bool isPalindrome(int x) {
if (x < 0) {
return false;
}
if (x == 0) {
return true;
}
vector<int> arr;
while(x) {
arr.push_back(x % 10);
x /= 10;
}
int s = arr.size();
for (auto i = 0; i <= s / 2; i++) {
if (arr[i] != arr[s-i-1]) {
return false;
}
}
return true;
}
2.进阶做法
执行用时:8ms,8.2MB
思想:官方题解,相当巧妙!为了避免溢出问题,可以不将全部整数翻转,而是只翻转一半,和另一半进行相等比较
实现:特殊情况依然单独拉出来处理;翻转一半的操作由比较 x 和 reverse 的大小来实现;循环结束后,reverse 要么和 x 位数相同,要么多一位;位数相同时,代表输入 x 是偶数位,直接比较 reverse 和 x,如果相等显然可以说明是回文数;位数不同时,代表输入 x 是奇数位,reverse 多出来的最后一位正好是输入 x 的中间位,不影响回文数的判断,可以用 /10 直接去掉
bool isPalindrome(int x) {
if (x < 0 || ((x % 10 == 0) && x !=0)) {
return false;
}
int reverse = 0;
// 翻转一半的实现,重点理解!
while (x > reverse) {
reverse = reverse * 10 + x % 10;
x /= 10;
}
return x == reverse || x == reverse / 10;
}
3.震惊做法
执行用时:8ms,8.1MB
思想:......原来还是可以用整数翻转的,但是要使用 long long 类型避免溢出
bool isPalindrome(int x) {
if(x < 0)
return false;
int temp = x;
long long reverse = 0;
while(temp) {
reverse *= 10;
reverse += temp % 10;
temp /= 10;
}
if(reverse == x)
return true;
else
return false;
}
4.神仙做法
执行用时:4ms,8MB
思想:主体部分还是第三种方法,但是这第一行...完全看不懂;大家可以参考这篇博文,这一行代码的用途就是解除一些默认操作,以此来提高效率(我以后也要加这一行→_→不过还是要理解,不能无脑加哦)
// 提高效率的关键代码!!!
static int x = [](){ios::sync_with_stdio(false); cin.tie(nullptr); return 0; }();
class Solution {
public:
bool isPalindrome(int x) {
int numSrc = x;
long long numDst = 0;
if (x < 0) {
return false;
}
while (numSrc) {
numDst = numDst * 10 + numSrc % 10;
numSrc /= 10;
}
return (numDst == x);
}
};
这几天做下来的感受就是,简单级别的题目,大家的思路都大致相同;即便是效率最高的那些代码,在思路上也差不离,但是会做细节的处理,不会有多余的变量或运算