整数反转(ReverseInteger)
asd
今天我来写一下 整数反转 的这一题,我们先目标把 简单难度 的题给刷了
题目描述
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
- 栗子 1:
输入: 123
输出: 321
- 栗子 2:
输入: -123
输出: -321
- 栗子 3:
输入: 120
输出: 21
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [$-2^{31}$, $2^{31}-1$]。请根据这个假设,如果反转后整数溢出那么就返回 0
。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-i...
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
自解
当时看到题目后,第一眼看到的想法就是int
转String
后再转char[]
数组后循环颠倒它的位置,后再转为int
返回,最后自己欠缺考虑=。=
没有考虑边缘值,和溢出的问题,最后用自己的方法没有通过,这样提醒我以后写代码时候要考虑和注意边缘值还有数据溢出的问题。下面会有正确解法,还是自己的经验不够会这样想着解题。
没有成功:边缘值无法通过测试 -2147483648
自己当时的解题思路:
- 第一步直接判断排除溢出的
-2147483648
治标不治本(这样写代码妈见打) - 在判断一下正负数,用flag记录下后面返回输出时候用到
- 获取
X
的绝对值,转换为String
String
再转换为char[]
进行循环翻转拼接- 最后利用
BigDecimal
转换为int
,根据flag
转化为应该的正负数输出(为什么要用BigDecimal
呢,因为别的包装类都会溢出.....) - 唔好学我鸭!
上代码
// 边缘值无法通过测试 -2147483648
public static int reverse(int x) {
if (String.valueOf(x).equals("-2147483648")) {
return 0;
}
Boolean flag = x>=0 ? true:false;
String a = String.valueOf(Math.abs(x));
String temp = "";
char[] chars = a.toCharArray();
for (int i=0; i<chars.length; i++) {
temp = chars[i] + temp;
}
BigDecimal l = new BigDecimal(temp.trim());
log.warn(String.valueOf(l));
if (flag) {
int result = l.intValue();
if (String.valueOf(result).equals(String.valueOf(l))) {
return l.intValue();
} else {
return 0;
}
} else {
int result = l.intValue();
if (String.valueOf(result).equals(String.valueOf(l))) {
return result * -1;
} else {
return 0;
}
}
}
正解
后面看了官方的题解后,是需要考虑是否溢出。
注意点:
- 如果
temp = rev * 10 + pop
导致溢出,那么一定会有rev >= (Integer.MAX_VALUE / 10)
- 如果
rev > (Integer.MAX_VALUE / 10)
,那么temp = rev * 10 + pop
一定会溢出 - 如果
rev == (Integer.MAX_VALUE / 10)
,那么只要pop > 7,temp = rev * 10 + pop
就会溢出
理解思路:
- 先要理解
Integer
的溢出,大于Integer.MAX_VALUE
或者小于Integer.MIN_VALUE
就会报错 - 下面首先把
x
判断是否为 0,不是就先进行%
余操作得到pop
x
为什么要x /= 10
就是x = x / 10
这里就是要进行翻转的关键了,看一下下面的一段代码 栗子
// 假设我们输入的是12345,第一个循环
int rev = 0; //用来存储最后的结果
int x = 12345;
int pop = 12345 % 10; // pop = 5 (获取到了个位数)
x /= 10; // (12345 / 10) = 1234 (int没有小数自动取整)
rev = rev * 10 + pop; // 0 * 10 + 5 = 5 (rev的值为5)
// 第二个循环 (x=1234,rev=5)
int pop = x % 10; // pop = 4
x /= 10; // (1234 / 10) = 123
rev = rev * 10 + pop; // 5 * 10 + 4 = 54 (rev的值为54)
// 没错这里已经翻转了2个数了后面的也是同理
.....
- 正负数都一样的
代码:
public static int reverseTwo(int x) {
int rev = 0;
while (x != 0) {
int pop = x % 10;
x /= 10;
if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) return 0;
if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) return 0;
rev = rev * 10 + pop;
}
return rev;
}
总结
这就是这次的整数翻转了,希望大家不要学我开始的思路解法,写代码时候大家得考虑 溢出 的问题哦。
本作品采用《CC 协议》,转载必须注明作者和本文链接