大家好,我是Zac!马上就到10月24日了,那可是是我们程序员的节日!好久不发题解了,那今天我们就爽一波,发一道力扣的题解!
T1:回文数
题目传送门:传送!
题目描述
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
- 例如,
121是回文,而123不是。
示例 1:
输入:x = 121 输出:true
示例 2:
输入:x = -121 输出:false 解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
输入:x = 10 输出:false 解释:从右向左读, 为 01 。因此它不是一个回文数。
提示:
-2^31 <= x <= 2^31 - 1
进阶:你能不将整数转为字符串来解决这个问题吗?(不能)
解题思路(字符串版)
这道题在这种做法下是一道水题,只要你找到方法。
我们先分析一下给的默认代码:
class Solution {
public:
bool isPalindrome(int x) {
}
};
可以发现,题目给了一个int类型的变量?好吧,我无语了😑,题目说是 :-2^31 <= x <= 2^31 - 1,但你给了一个int?那就按照你的这个int来做吧!
解法一:字符串反转法
分析题目:回文数的核心特征就是正着读和反着读一样。既然数字可以当作字符串处理,那直接反转字符串比较岂不美哉?
提出假设:把整数转成字符串,反转后如果和原字符串相同,就是回文数。
验证假设:
-
121 → "121" → 反转"121" → 相同 ✓
-
-121 → "-121" → 反转"121-" → 不同 ✓
-
10 → "10" → 反转"01" → 去除前导0→得到不同 ✓
得出结论:字符串反转法简单粗暴有效,就是有点"作弊"嫌疑——题目明明说是整数,我们却偷偷转成了字符串(好像没说不行哈?)
直接给我上代——码!
AC Code:
class Solution {
public:
bool isPalindrome(int x) {
string a = to_string(x);
string b = a;
reverse(b.begin(), b.end());
for (int i = 0; i < a.size(); i++) {
if (a[i] != b[i]) {
return false;
}
}
return true;
}
};
class Solution {
public:
bool isPalindrome(int x) {
string a = to_string(x); // 转换为string
string b = a; // 赋值,方便后面的反转判断
reverse(b.begin(), b.end()); // 反转
for (int i = 0; i < a.size(); i++) { // 判断是否一样
if (a[i] != b[i]) {
return false;
}
}
return true;
}
};
class Solution {
public:
bool isPalindrome(int x) {
string a=to_string(x);
string b=a;
reverse(b.begin(),b.end());
for(int i =0;i<a.size();i++){
if(a[i]!=b[i]) return false;
}
return true;
}
};
class Solution {
public:
bool isPalindrome(int x) {
string a=to_string(x); // 转换为string
string b=a; // 赋值,方便后面的反转判断
reverse(b.begin(),b.end()); // 反转
for(int i =0;i<a.size();i++){ // 判断反转后是否一样
if(a[i]!=b[i]) return false;
}
return true;
}
};
解法二:字符串双指针
解题思路:回文就是首尾对称,那何必整个反转?从两头往中间比较就行了,发现不对劲立马开溜!
分析代码:题目还是给那个int,看来是铁了心要我们处理整数。不过我们可以继续"作弊"转字符串。
提出假设:用两个指针从字符串两端向中间移动,逐个比较字符,不一样就直接返回false。
验证假设:
-
121:左'1'=右'1' → 左'2'=右'2' → 成功 ✓
-
123:左'1'=右'3'?不相等 → 立即返回false ✓
-
-121:第一个字符'-'和最后一个字符'1'就不一样 → 直接false ✓
得出结论:双指针法比完全反转更聪明,发现不匹配就能提前退出,效率更高,而且代码写起来很酷!
直接给我上代——码!
AC Code:
class Solution {
public:
bool isPalindrome(int x) {
string s = to_string(x);
int left = 0, right = s.size() - 1;
while (left < right) {
if (s[left] != s[right]) {
return false;
}
left++;
right--;
}
return true;
}
};
class Solution {
public:
bool isPalindrome(int x) {
string s = to_string(x); // 转字符串
int left = 0, right = s.size() - 1; // 左右指针
while (left < right) { // 向中间靠拢
if (s[left] != s[right]) { // 发现不一样
return false; // 直接开溜
}
left++; // 左指针右移
right--; // 右指针左移
}
return true;
}
};
class Solution {
public:
bool isPalindrome(int x) {
int left=0,right=s.size()-1;
while(left<right){
if(s[left]!=s[right]){
return false;
}
left++;
right--;
}
return true;
}
};
class Solution {
public:
bool isPalindrome(int x) {
string s=to_string(x); // 转字符串
int left=0,right=s.size()-1; // 左右指针
while(left<right){ // 向中间靠拢
if(s[left]!=s[right]){ // 发现不一样
return false; // 直接开溜
}
left++; // 左指针右移
right--; // 右指针左移
}
return true;
}
};
解题思路(数学版)
解法三:数学反转
解题思路:题目要求处理整数,那我们应该用数学方法才够"纯正"。反转数字可以通过数学运算实现,这样才配得上这道题的"整数"标签!
分析代码:还是那个int x,但这次我们要用真正的数学方法了!
提出假设:通过取模和除法运算反转数字,然后比较原数字与反转后的数字。
验证假设:
-
121 → 反转得到121 → 相等 ✓
-
123 → 反转得到321 → 不相等 ✓
发现问题:反转后的数字可能溢出!比如2147483647反转后就溢出了,而且完全反转效率也不高。
改进假设:只反转一半数字!这样既避免了溢出,又提高了效率,我真是个天才!
最终方案:反转后半部分,然后比较前半部分和反转后的后半部分。
直接上代——码!
AC Code:
class Solution {
public:
bool isPalindrome(int x) {
if (x < 0) return false;
if (x < 10) return true;
if (x % 10 == 0) return false;
int reversed = 0;
while (x > reversed) {
reversed = reversed * 10 + x % 10;
x /= 10;
}
return x == reversed || x == reversed / 10;
}
};
class Solution {
public:
bool isPalindrome(int x) {
if (x < 0) return false; // 负数肯定不是回文
if (x < 10) return true; // 个位数肯定是回文
if (x % 10 == 0) return false; // 以0结尾的不是回文
int reversed = 0; // 存储反转的后半部分
while (x > reversed) { // 当原数大于反转数时继续
reversed = reversed * 10 + x % 10; // 反转数字
x /= 10; // 原数去掉最后一位
}
// 偶数位:x == reversed
// 奇数位:x == reversed/10 (去掉中间那位)
return x == reversed || x == reversed / 10;
}
};
class Solution {
public:
bool isPalindrome(int x) {
if(x<0) return false;
if(x<10) return true;
if(x%10==0) return false;
int reversed=0;
while(x>reversed){
reversed=reversed*10+x%10;
x/=10;
}
return x==reversed||x==reversed/10;
}
};
class Solution {
public:
bool isPalindrome(int x) {
if(x<0) return false; // 负数肯定不是回文
if(x<10) return true; // 个位数肯定是回文
if(x % 10==0) return false; // 以0结尾的不是回文
int reversed=0; // 存储反转的后半部分
while(x>reversed){ // 当原数大于反转数时继续
reversed=reversed*10+x%10; // 反转数字
x/=10; // 原数去掉最后一位
}
// 偶数位:x==reversed
// 奇数位:x==reversed/10 (去掉中间那位)
return x==reversed||x==reversed/10;
}
};
解法四:完全反转数字法
解题思路:既然要反转,那就彻底一点!把整个数字都反转过来比较,简单直接!
分析代码:还是那个int x,这次我们用long long来避免溢出问题。
提出假设:完全反转整个数字,然后比较反转前后是否相等。
验证假设:
-
121 → 反转121 → 相等 ✓
-
123 → 反转321 → 不相等 ✓
-
-121 → 反转121-?不对,负数直接返回false ✓
得出结论:完全反转法最直观易懂,就是要注意溢出问题,所以用了long long。
血的教训:

直接给我上代——码!
AC Code:
class Solution {
public:
bool isPalindrome(int x) {
if (x < 0) return false;
long long reversed = 0;
int temp = x;
while (temp != 0) {
reversed = reversed * 10 + temp % 10;
temp /= 10;
}
return x == reversed;
}
};
class Solution {
public:
bool isPalindrome(int x) {
if (x < 0) return false; // 负数不是回文
long long reversed = 0; // 用long long防止溢出
int temp = x; // 保存原始值
while (temp != 0) { // 反转整个数字
reversed = reversed * 10 + temp % 10;
temp /= 10;
}
return x == reversed; // 比较是否相等
}
};
class Solution {
public:
bool isPalindrome(int x) {
if(x<0) return false;
long long reversed=0;
int temp=x;
while(temp!=0){
reversed=reversed*10+temp%10;
temp/=10;
}
return x==reversed;
}
};
class Solution {
public:
bool isPalindrome(int x) {
if(x<0) return false; // 负数不是回文
long long reversed=0; // 用long long防止溢出
int temp=x; // 保存原始值
while(temp!=0){ // 反转整个数字
reversed=reversed*10+temp%10;
temp/=10;
}
return x==reversed; // 比较是否相等
}
};
总结
四种解法各有特色:
-
字符串反转法:简单粗暴,适合新手
-
双指针法:聪明伶俐,提前退出
-
数学反转法:优雅高效,真正的大佬解法
-
完全反转法:直观易懂,就是要注意溢出
个人最推荐解法三和解法一,非常符合题目要求!(指的是可不可以不用字符串捏?以及 不用字符串怎么解捏?)
重中之重!!!
在文章的最后,提前祝各位神犇小伙伴们1024快乐!对了,点赞收藏关注一个再走呗?
196

被折叠的 条评论
为什么被折叠?



