回文数
问题描述
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
示例 1:
输入: 121
输出: true
示例 2:
输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。
思路1:暴力求解法
这里以c/c++语言来具体化
具体思路开始(可以参考下面几幅图)
- 翻转整个数,然后对比原来的数
注意:这里翻转可能会溢出int,所以不能将翻转的数设为int,考虑到不同的机器字节不同这里设为long long(32位机器int 为4个字节32位,long 也为4个字节字节;64位机器int为 4个字节,long为8个字节)
代码
/*暴力求解*/
class Solution {
public:
bool isPalindrome(int x) {
if(x < 0) return false;
int pop = 0;
long long re = 0;
int temp = x;
while(temp){
pop = temp % 10;
re = re * 10 + pop;
temp = temp / 10;
}
if(re==x) return true;
else return false;
}
};
思路2:转化字符串
- 将形参转化成字符串,用到to_string(x)
- 反转字符串,用到std::reverse(str_x.begin() , str_x.end())
- 最后用字符串流写入到re中
解释一下字符串流,具体可参考这篇文章
stringstream是 C++提供的另一个字串型的串流(stream)物件,和之前学过的iostream、fstream有类似的操作方式。要使用stringstream,必须先加入这一行:
#include < sstream >
字符串流的用法
类型转化
1.string转化成int
string result = "10000";
int n = 0;
stream << result;
stream >> n; //n等于10000
- int转化成string
stringstream ss;
string s;
int i = 1000;
ss << i;
ss >> s;//s已经为字符串
cout << s << endl;
- 在类型转中使用模板
template<class out_type, class in_value>
out_type convert(const in_value & t)
{
stringstream stream;
stream << t;//向流中传值
out_type result;//这里存储转换结果
stream >> result; //向result中写入值
return result;
}
具体例子来调用类模板函数
double dou;
string str;
string s = "3.1415";
dou = convert <double> (s); //dou等于3.1415,这里类模板缺省,实际为convert <double,string>
str = convert <string> (110011.0); //str等于"110011"
通过上述三个例子,了解了stringstream就可以去理解下面的代码了
代码
/*
转化为字符串
*/
class Solution {
public:
bool isPalindrome(int x) {
long long re = 0;
if(x < 0) return false;
string str_x = to_string(x);//转换成字符串
std::reverse(str_x.begin() , str_x.end());//进行反转
stringstream ss(str_x);
ss >> re;//结果写入re
if(re==x) return true;
else return false;
}
};
思路3:对折法
- 翻转后一半的数
- 与原来前一半的数进行比较
- 奇数点相对要多一步,因为后一半的数比前一半多一位数,则后一半的数除以10取整,偶数直接比较前一半和后一半即可
可以知道对折法是暴力求解法的一个优化,不用去遍历整个整数,只用遍历一半即可
代码
class Solution {
public:
bool isPalindrome(int x) {
int midrev=0;//存储后半部分数字的反转结果
if (x < 0||(x%10==0&&x!=0)) return false;//排除负数和最后一位数字为0的数字
while(x>midrev)
{
midrev=midrev*10+x%10;
x/=10;
}
return midrev==x||midrev/10==x;//数字个数为偶数和奇数分两种情况
}
};
这个回文数的题相对来说简单一点,但是可以提供多种解题思路,降低时间复杂度
如果本文对宝宝打开思路有帮助,可以点个赞哦~