一般是要判断是数字a是10倍的速度增长,判断
a > Integer.MAX_VALUE/10 || (a == Integer.MAX_VALUE/10 && a1 > 7)
a < Integer.MIN_VALUE/10 || (a == Integer.MIN_VALUE/10 && a1 < -8)
以上条件成立,则说明a数字再增长10倍,就会溢出
其中(a1是最后1位)
INFO
有时,后半部份a == Integer.MAX_VALUE/10 && a1 > 7
可能会被省略,具体要看题目的要求 作为对比,下面看两个题的代码
数字反转
package algorithm.数字和数学;
/**
*
* [7. 整数反转](https://leetcode.cn/problems/reverse-integer/description/)
*
*/
public class reverse {
// 第一种写法:标准写法
public static int reverse(int x) {
int res = 0;
while (x != 0) {
// 获得末尾数字
int tmp = x % 10;
// 判断是否大于最大32位整数,也可以使用Integer.MAX_VALUE/10来代替214748364
if (res > 214748364 || (res == 214748364 && tmp > 7)) return 0;
// 判断是否小于最下的32位整数
if (res<-214748364 || (res == -214748364 && tmp < -8)) return 0;
res = res * 10 + tmp;
x /= 10;
}
return res;
}
// 最大正整数:2147483647 == /10 ==> 214748364
// 最小负整数:-2147483648 == /10 ==> -214748364
// 第二种写法:
// ⚠️⚠️为什么上面的代码里(res == 214748364 && tmp > 7)和(res == -214748364 && tmp < -8)删掉也是对的
// 因为,如果输入的数字位数小于【最大数字的位数】,那么一定是不会溢出的
// 拿463847412举例翻转之后是214748364是9位数字,这个数正好是【最大正整数的10分之一】
// 翻转前8位的时候,都比【最大正整数的10分之一】要小,因为【最大正整数的10分之一】是9位数字
// 剩下最后1位数字的时候,x/=10就是0了,退出了循环
// 也就是说,无论最后1位是多少,因为位数小于【最大数字的位数】,不等到res == Integer.MAX_VALUE/10这个判断就已经退出循环了
// 如果输入数字位数大于等于【最大数字的位数】
// 先看大于的情况,是不存在大于的情况的,因为输入数字就溢出了,显然是不可能的
// 那么只有位数等于的情况
// 当 前9位正好等于214748364时,最后1位不可能为7
// 因为 214748364是反转得来的,10位的输入数字,要想不溢出,高位必须是1或者2,不可能为7
// 同理,也不需要判断 -8
public static int reverse2(int x) {
int res = 0;
while (x != 0) {
int tmp = x % 10;
if (res > Integer.MAX_VALUE/10 || res < Integer.MIN_VALUE/10) return 0;
res = res * 10 + tmp;
x /= 10;
}
return res;
}
public static void main(String[] args) {
}
}
字符串转换整数
package algorithm.字符串;
/**
*
* [8. 字符串转换整数 (atoi)](https://leetcode.cn/problems/string-to-integer-atoi/description/)
*
* 这里不涉及算法,涉及日常编程的边界问题和数据处理
*
*/
public class myAtoi {
public int myAtoi(String s) {
int len = s.length();
char[] charArray = s.toCharArray();
// 1. 去除前导空格
int index = 0;
while (index < len && charArray[index] == ' ') {
index++;
}
// 2. 如果已经遍历完成(针对极端用例 " ")
if (index == len) return 0;
// 3. 如果出现符号字符,仅第1个有效,并记录正负
int sign = 1;
char firstChar = charArray[index];
if (firstChar == '+') {
index++;
} else if (firstChar == '-') {
index++;
sign = -1;
}
// 4. 将后续出现的数字字符进行转换
// 不能使用long类型
int res = 0;
while (index < len) {
char currChar = charArray[index];
// 先判断不合法情况
if (currChar > '9' || currChar < '0') {
break;
}
// 解决溢出问题的经典处理方式
if (res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && (currChar - '0') > Integer.MAX_VALUE % 10)) {
return Integer.MAX_VALUE;
}
if (res < Integer.MIN_VALUE / 10 || (res == Integer.MIN_VALUE / 10 && (currChar - '0') > -(Integer.MIN_VALUE % 10))) {
return Integer.MIN_VALUE;
}
// 合法情况下,才考虑转换,每一步都把符号位乘进去
res = res * 10 + sign * (currChar - '0');
index++;
}
return res;
}
}