/** * 官方题解 */ publicintreverse(int x){ int res = 0; while (x != 0) { int pop = x % 10; // 预先检查是否溢出 if (res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && pop > Integer.MAX_VALUE % 10)) { return0; } // 预先检查是否溢出 if (res < Integer.MIN_VALUE / 10 || (res == Integer.MIN_VALUE / 10 && pop < Integer.MIN_VALUE % 10)) { return0; } res = res * 10 + pop; x /= 10; } return res; }
但是,再仔细深入想想:这道题给定的参数 x 本身就是合法的 int 值,而 int 的最大值和最小值开头的数字只能是 1 或 2,所以如果有最后一次循环的话,pop 的值一定是 1 或 2,因此 (res == INT_MAX / 10 && pop > 7) 和 (res == INT_MIN / 10 && pop < -8) 这两个判断肯定是不会成立的,可以省略。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/** * 官方题解代码优化 */ publicintreverse(int x){ int res = 0; while (x != 0) { int pop = x % 10; // 预先检查是否溢出 if (res > Integer.MAX_VALUE / 10 || res < Integer.MIN_VALUE / 10) { return0; } res = res * 10 + pop; x /= 10; } return res; }
publicintreverse(int x){ int ans = 0; while (x != 0) { // 判断是否溢出 if ((ans * 10) / 10 != ans) { return0; } ans = ans * 10 + x % 10; x /= 10; } return ans; }
骚操作三
转为 long 处理。
int 类型范围太小导致溢出了,那么我们就找个范围更大的类型来处理。
1 2 3 4 5 6 7 8 9 10 11 12 13
publicintreverse(int x){ long result = 0; while (x != 0) { int pop = x % 10; result = result * 10 + pop; // 判断 int 类型是否溢出 if (result > Integer.MAX_VALUE || result < Integer.MIN_VALUE) { return0; } x /= 10; } return (int) result; }
骚操作四
转为字符串处理,不过也用到了 long 类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
publicintreverse(int x){ if (x == Integer.MIN_VALUE || x == 0) { return0; } String strReverse = new StringBuilder(Integer.toString(Math.abs(x))).reverse().toString(); long result = Long.parseLong(strReverse); // 负数转回负数 if(x < 0) { result = -result; } // 判断 int 类型是否溢出 if(result > Integer.MAX_VALUE || result < Integer.MIN_VALUE) { return0; } return (int) result; }
/** * 单点更新:把数组 i 位置的值加上 v */ publicvoidupdate(int i, int v){ // 类比上图,从下到上进行更新 while (i <= this.len) { this.tree[i] += v; i += lowbit(i); } }
/** * 区间查询:查询序列 [1 ⋯ i] 区间的区间和,即 i 位置的前缀和 */ publicintquery(int i){ // 类比上图,从右到左查询 int sum = 0; while (i > 0) { sum += this.tree[i]; i -= lowbit(i); } return sum; }