文章目录
一、题目
1. 题目描述
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
2. 示例
示例1:
输入: 123
输出: 321
示例 2:
输入: 120
输出: 21
3. 题目解析
要求的是32位有符号整数,则其数值范围为 [ − 2 31 , 2 31 − 1 ] [−2^{31}, 2^{31} − 1] [−231,231−1] 。请根据这个假设,如果反转后整数溢出那么就返回 0。但是函数的参数是int类型。
二、解法
1. 个人解法
(1)代码
/**
* first int变char[],遍历移动法
* @param x
* @return
*/
public int reverse(int x) {
if (x > (Math.pow(2, 31) - 1) || x < (Math.pow(-2, 31))) {
return 0;
}
// 将int类型转换为String
String str = String.valueOf(x);
// 将String类型转换为char数组
char[] ch = str.toCharArray();
// 整体反转
for (int i = 0; i < ch.length / 2; i++) {
char temp = ch[i];
ch[i] = ch[ch.length - i - 1];
ch[ch.length - i - 1] =temp;
}
// 将负号挪第一位
if (ch[ch.length - 1] == '-') {
for(int i=ch.length-1;i>0;i--){
ch[i]=ch[i-1];
}
ch[0]='-';
}
// char[]变String
String strOut = new String(ch);
// String变int
int out = Integer.parseInt(strOut);
if (out > (Math.pow(2, 31) - 1) || out < (Math.pow(-2, 31))) {
return 0;
}
return out;
}
(2)失败反思
没有考虑到,整数反转后,发生的溢出情况。
比如2147483647,本身是不溢出的,但是反转后会发生溢出,这个时候由String类型转换为int类型会报错。
(3)改进
a.改进点
1.使用StringBuffer的reverse()函数进行反转
2.将int转换为String的时候分正数和负数来进行,如果是负数,先利用Math.abs()函数取绝对值,再拼接一个“-”。
3.String转换回int类型的时候,为了避免溢出错误,先转换为Long类型,判断是否溢出,再进行转int类型操作。
b.代码
/**
* second first的改进 StringBuffer+绝对值
*
* @param x
* @return
*/
public int reverse1(int x) {
String str;
// StringBuffer的reverse()方法可以直接反转字符串
// 可以利用取绝对值再对负数拼接负号的方式来处理负数
if (x >= 0) {
StringBuffer s = new StringBuffer(String.valueOf(x));
str = s.reverse().toString();
} else {
StringBuffer s = new StringBuffer(String.valueOf(Math.abs(x)));
str = "-" + s.reverse().toString();
}
Long out = Long.parseLong(str);
if (out > (Math.pow(2, 31) - 1) || out < (Math.pow(-2, 31))) {
return 0;
}
return Integer.parseInt(str);
}
(4)改进后的代码的失败反思
这次是没有考虑到Math.abs()函数的溢出问题,比如说:-2147483648,函数处理后的返回值为:-2147483648
(5)再次改进
查阅资料后得知,为了避免Math.abs()函数的越界,参数可以转换为Long类型后再取绝对值:
StringBuffer s = new StringBuffer(String.valueOf(Math.abs((long)x)));
(6)算法分析
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
n
)
O(n)
O(n)
(7)提交截图
第一次错误
反转后的整数溢出导致。(1147483647)
第二次错误
Math.abs溢出导致。(-2147483648)
第三次正确提交
2. 官网高星解法
(1)除10取余法
解法分析
不转化成字符串也可以解决这个问题:
1.将整数除以10取余可以得到最后一位的值
2.将上一次得到的值乘以10加这一次得到的最后一位的值
3.重复12直至整数为0,将此整数反转
代码
/**
* 除10取余法
* @param x
* @return
*/
public int reverse2(int x){
long sum=0;
// 当x=0的时候结束循环
while(x!=0){
// 取余
int temp=x%10;
// x跟着除以10以方便下一次循环取的下一位
x=x/10;
// 得到结果
sum=sum*10+temp;
}
// 判断是否溢出
if (sum > (Math.pow(2, 31) - 1) || sum < (Math.pow(-2, 31))) {
return 0;
}
return (int)sum;
}
算法分析
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
1
)
O(1)
O(1)