007.整数反转
作者:沉默王二 发布时间:2023-12-28T14:36:09.406+0800
-
语雀专栏地址+密码可通过星球置顶帖查看:https://t.zsxq.com/15rEo9Pdu
-
技术派专栏地址:https://paicoding.com/column/7/ 7
-
这道题可以说完全重写了,给出两道大家完全都能掌握的题解,并且追加手绘图,大家会非常容易掌握,一道中等难度直接变身 easy 难度。
-
增加代码注释,这样大家更容易看懂并掌握题解;
-
增加参考资料,这样大家可以从零基础直接开刷,减轻新手刷题的阻力;
-
增加手绘图,这样大家更容易理解解题思路;
-
增加 ACM 输入输出,这样大家可以在 Intellij IDEA 中进行调试;
-
增加题解模拟,这样大家可以根据题解模拟整个题解过程,看完会有一种“哦哦”恍然大悟的感觉;
-
图片上传至 OSS 并配合 CDN,提升大家在技术派网站中的阅读体感。
-
另外,这一版本会作为 PDF 的终稿随后在星球进行发布。
二哥的 LeetCode 题解真的精辟——鲁迅(我没说)
题意
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例
输入:x=123
输入:x=-123输出:-321 输入:x=120输出:21 输入:x=0输出:0
难度
中等
分析 1
看到这题,我的第一感觉就是把 32 位的整数看成是一个字符串,然后直接调用 StringBuilder 的 reverse 方法,这样就可以完成反转了,对吧,完全可行。
剩下需要做的,就是处理一下负数的情况,还有超出边界的情况。
class Solution {
String reversed = new StringBuilder().append(Math.abs(x)).reverse().toString(); try { // 如果原始整数为负数,则反转后的结果也应该是负数 int result = Integer.parseInt(reversed); return (x < 0) ? result * -1 : result; } catch (NumberFormatException e) { // 捕获溢出异常并返回 0 return 0; } }}
①、Math.abs () 方法可以获取一个数的绝对值,比如Math.abs (-123)的结果就是123。
②、然后用 StringBuilder 的 append 方法将正数添加到字符串序列中。
③、调用 reverse 方法将字符串反转。我在《二哥的 Java 进阶之路》里曾讲过 reverse 方法 ,没看过源码的**球友 **可以回头看一眼。
int n = count - 1; // 字符序列的最后一个字符的索引
for (int j = (n-1) >> 1; j >= 0; j--) { int k = n - j; // 计算相对于 j 对称的字符的索引 char cj = value[j]; // 获取当前位置的字符 char ck = value[k]; // 获取对称位置的字符 value[j] = ck; // 交换字符 value[k] = cj; // 交换字符}
这个翻转的方法其实非常巧妙,从字符串的两端开始交换,直到中间位置,比从头到尾或者从尾到头要快一倍。
④、最后调用 Integer 的 parseInt 方法将字符串转换成整数,如果超出边界,就会抛出 NumberFormatException 异常 ,我们通过 try-catch 捕获这个异常,然后返回 0。如果是负数,就将结果乘以 -1。
来看一下题解的效率:
还不错,那其实我们可以再优化一下,不调用 StringBuilder 的 reverse 方法,我们可以自己实现一个翻转的方法,把 reverse 方法的源码拿过来改一改就行了。
class Solution {
String reversed = reverseString(String.valueOf(Math.abs(x))); try { // 如果原始整数为负数,则反转后的结果也应该是负数 int result = Integer.parseInt(reversed); return (x < 0) ? result * -1 : result; } catch (NumberFormatException e) { // 捕获溢出异常并返回 0 return 0; } }
private String reverseString(String s) { char[] value = s.toCharArray(); int n = value.length - 1; for (int j = (n-1) >> 1; j >= 0; j--) { int k = n - j; char cj = value[j]; char ck = value[k]; value[j] = ck; value[k] = cj; } return new String(value); }}
只不过,这样做的意义不大,换汤不换药而已,有没有更好的方法呢?
分析 2
对于一个整数来说,我们可以通过取余和除法来获取它的每一位,比如123,我们通过123 % 10来获取它的个位 3,123 / 10来把它的个位去掉,剩下 12;
然后通过12 % 10来获取它的十位 2,12 / 10来把它的十位去掉,剩下 1;
然后再通过1 % 10来获取它的百位 1,1 / 10来把它的百位去掉,剩下 0,这样就把整数的每一位都获取到了,获取知道就很好处理了,不断地乘以 10 累加就行了。
唯一需要注意的就是判断一下是否超出边界,这里我用了一个小技巧,就是在每次累加之前,先判断一下累加后的结果是否超出边界,如果超出边界,就直接返回 0,否则再累加。
class Solution {
int rev = 0; // 用于存储反转后的结果 while (x != 0) { int pop = x % 10; // 获取 x 的最后一位数字 x /= 10; // 移除 x 的最后一位数字
// 检查溢出:如果 rev > Integer.MAX_VALUE/10 或 rev < Integer.MIN_VALUE/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; // 将 pop 添加到 rev 的最后 } return rev; // 返回反转后的整数 }}
①、rev == Integer.MAX_VALUE / 10 && pop > 7
- Integer.MAX_VALUE 是 2147483647,Integer.MAX_VALUE / 10 则是 214748364。
- 当 rev 等于 214748364 时,乘以 10 再加上任何大于 7 的数字将导致整数溢出,比如说 214748364 * 10 + 8 = 2147483648 > Integer.MAX_VALUE(2147483647)。
②、rev == Integer.MIN_VALUE / 10 && pop < -8
- Integer.MIN_VALUE 是 -2147483648,Integer.MIN_VALUE / 10 则是 -214748364。
- 当 rev 等于 -214748364 时,乘以 10 再减去任何小于 -8 的数字将导致整数溢出,比如说 -214748364 * 10 - 9 = -2147483649 < Integer.MIN_VALUE(-2147483648)。
那如果说,写题解的时候,不想出现这种魔法数字(7 或者 -8),可以这样写:
class Solution {
int rev = 0; // 用于存储反转后的结果 while (x != 0) { int pop = x % 10; // 获取 x 的最后一位数字 x /= 10; // 移除 x 的最后一位数字
// 检查溢出:如果 rev > Integer.MAX_VALUE/10 或 rev < Integer.MIN_VALUE/10,则会溢出 if (rev > Integer.MAX_VALUE / 10 || (rev == Integer.MAX_VALUE / 10 && pop > Integer.MAX_VALUE % 10)) return 0; if (rev < Integer.MIN_VALUE / 10 || (rev == Integer.MIN_VALUE / 10 && pop < Integer.MIN_VALUE % 10)) return 0;
rev = rev * 10 + pop; // 将 pop 添加到 rev 的最后 } return rev; // 返回反转后的整数 }}
运行效率也非常喜人,直接击败 100% 的 Java 提交者。
总结
这道题其实算不上中等的难度,不论是直接调用 reverse 还是通过取余和除法来获取每一位,都是比较容易想到的方法,唯一需要考虑的就是边界问题。
力扣链接:https://leetcode.cn/problems/reverse-integer/submissions/
学过基本数据类型的球友应该知道,Java 中的整数类型有 4 种,分别是 byte、short、int 和 long,它们的取值范围如下:
其中 int 类型的取值范围就是 32 位的有符号整数的取值范围,所以我们可以把 int 类型的最大值和最小值作为边界来判断是否溢出。
32 位的有符号整数的取值范围是从 -2^31 到 2^31 - 1,其中一位用于表示符号(正或负),剩下的 31 位用于表示数值,这意味着其范围是 -2,147,483,648(即 -2^31)到 2,147,483,647(即 2^31 - 1)。
在二进制系统中,每个位(bit)可以表示两个状态,通常是 0 和 1。对于 32 位得正二进制数,除去符号位,从右到左的每一位分别代表 2^0, 2^1, 2^2, ..., 2^30,这个二进制数转换为十进制就是 2^0 + 2^1 + 2^2 + ... + 2^30,也就是 2,147,483,647。
第一种题解很容易想到,涉及到的知识点有:
第二种题解也不难想到,主要就是除法和取余的运算,以及边界的判断,涉及到的知识点有:
一步一个脚印
不积跬步无以至千里,不积小流无以成江海。LeetCode - 100天从算法小白到卷王正式启动了,我们计划周一到周五至少每天更新一篇,周六周日更新一篇,目标 300 道 LeetCode 经典题。
该题解目前只针对**二哥编程星球 **的球友开放,如果你也想一起打卡学习算法的话,扫下面的优惠券加入我们吧,星球目前 4100+ 人,定价 149 元,从当初的 99 元一路涨上来的,所以早就是优势,别再犹豫了。
(优惠券仅 300 张,数量有限)
一个人可以走得很快,但一群人才能走得更远。如果想去面中大厂的话,LeetCode 几乎是必刷的,二哥的 LeetCode 题解通俗易懂、图文并茂,理解给你举一反三的解题能力,冲鸭。
- 语雀专栏地址+密码可通过星球置顶帖查看:[https://t.zsxq.com/15rEo9Pdu](https://t.zsxq.com/15rEo9Pdu)
-
技术派专栏地址:https://paicoding.com/column/7/ 7
-
这道题可以说完全重写了,给出两道大家完全都能掌握的题解,并且追加手绘图,大家会非常容易掌握,一道中等难度直接变身 easy 难度。
-
增加代码注释,这样大家更容易看懂并掌握题解;
-
增加参考资料,这样大家可以从零基础直接开刷,减轻新手刷题的阻力;
-
增加手绘图,这样大家更容易理解解题思路;
-
增加 ACM 输入输出,这样大家可以在 Intellij IDEA 中进行调试;
-
增加题解模拟,这样大家可以根据题解模拟整个题解过程,看完会有一种“哦哦”恍然大悟的感觉;
-
图片上传至 OSS 并配合 CDN,提升大家在技术派网站中的阅读体感。
-
另外,这一版本会作为 PDF 的终稿随后在星球进行发布。
二哥的 LeetCode 题解真的精辟——鲁迅(我没说)
题意
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例
输入:x=123
输入:x=-123输出:-321 输入:x=120输出:21 输入:x=0输出:0
难度
中等
分析 1
看到这题,我的第一感觉就是把 32 位的整数看成是一个字符串,然后直接调用 StringBuilder 的 reverse 方法,这样就可以完成反转了,对吧,完全可行。
剩下需要做的,就是处理一下负数的情况,还有超出边界的情况。
class Solution {
String reversed = new StringBuilder().append(Math.abs(x)).reverse().toString(); try { // 如果原始整数为负数,则反转后的结果也应该是负数 int result = Integer.parseInt(reversed); return (x < 0) ? result * -1 : result; } catch (NumberFormatException e) { // 捕获溢出异常并返回 0 return 0; } }}
①、Math.abs () 方法可以获取一个数的绝对值,比如Math.abs (-123)的结果就是123。
②、然后用 StringBuilder 的 append 方法将正数添加到字符串序列中。
③、调用 reverse 方法将字符串反转。我在《二哥的 Java 进阶之路》里曾讲过 reverse 方法 ,没看过源码的**球友 **可以回头看一眼。
int n = count - 1; // 字符序列的最后一个字符的索引
for (int j = (n-1) >> 1; j >= 0; j--) { int k = n - j; // 计算相对于 j 对称的字符的索引 char cj = value[j]; // 获取当前位置的字符 char ck = value[k]; // 获取对称位置的字符 value[j] = ck; // 交换字符 value[k] = cj; // 交换字符}
这个翻转的方法其实非常巧妙,从字符串的两端开始交换,直到中间位置,比从头到尾或者从尾到头要快一倍。
④、最后调用 Integer 的 parseInt 方法将字符串转换成整数,如果超出边界,就会抛出 NumberFormatException 异常 ,我们通过 try-catch 捕获这个异常,然后返回 0。如果是负数,就将结果乘以 -1。
来看一下题解的效率:
还不错,那其实我们可以再优化一下,不调用 StringBuilder 的 reverse 方法,我们可以自己实现一个翻转的方法,把 reverse 方法的源码拿过来改一改就行了。
class Solution {
String reversed = reverseString(String.valueOf(Math.abs(x))); try { // 如果原始整数为负数,则反转后的结果也应该是负数 int result = Integer.parseInt(reversed); return (x < 0) ? result * -1 : result; } catch (NumberFormatException e) { // 捕获溢出异常并返回 0 return 0; } }
private String reverseString(String s) { char[] value = s.toCharArray(); int n = value.length - 1; for (int j = (n-1) >> 1; j >= 0; j--) { int k = n - j; char cj = value[j]; char ck = value[k]; value[j] = ck; value[k] = cj; } return new String(value); }}
只不过,这样做的意义不大,换汤不换药而已,有没有更好的方法呢?
分析 2
对于一个整数来说,我们可以通过取余和除法来获取它的每一位,比如123,我们通过123 % 10来获取它的个位 3,123 / 10来把它的个位去掉,剩下 12;
然后通过12 % 10来获取它的十位 2,12 / 10来把它的十位去掉,剩下 1;
然后再通过1 % 10来获取它的百位 1,1 / 10来把它的百位去掉,剩下 0,这样就把整数的每一位都获取到了,获取知道就很好处理了,不断地乘以 10 累加就行了。
唯一需要注意的就是判断一下是否超出边界,这里我用了一个小技巧,就是在每次累加之前,先判断一下累加后的结果是否超出边界,如果超出边界,就直接返回 0,否则再累加。
class Solution {
int rev = 0; // 用于存储反转后的结果 while (x != 0) { int pop = x % 10; // 获取 x 的最后一位数字 x /= 10; // 移除 x 的最后一位数字
// 检查溢出:如果 rev > Integer.MAX_VALUE/10 或 rev < Integer.MIN_VALUE/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; // 将 pop 添加到 rev 的最后 } return rev; // 返回反转后的整数 }}
①、rev == Integer.MAX_VALUE / 10 && pop > 7
- Integer.MAX_VALUE 是 2147483647,Integer.MAX_VALUE / 10 则是 214748364。
- 当 rev 等于 214748364 时,乘以 10 再加上任何大于 7 的数字将导致整数溢出,比如说 214748364 * 10 + 8 = 2147483648 > Integer.MAX_VALUE(2147483647)。
②、rev == Integer.MIN_VALUE / 10 && pop < -8
- Integer.MIN_VALUE 是 -2147483648,Integer.MIN_VALUE / 10 则是 -214748364。
- 当 rev 等于 -214748364 时,乘以 10 再减去任何小于 -8 的数字将导致整数溢出,比如说 -214748364 * 10 - 9 = -2147483649 < Integer.MIN_VALUE(-2147483648)。
那如果说,写题解的时候,不想出现这种魔法数字(7 或者 -8),可以这样写:
class Solution {
int rev = 0; // 用于存储反转后的结果 while (x != 0) { int pop = x % 10; // 获取 x 的最后一位数字 x /= 10; // 移除 x 的最后一位数字
// 检查溢出:如果 rev > Integer.MAX_VALUE/10 或 rev < Integer.MIN_VALUE/10,则会溢出 if (rev > Integer.MAX_VALUE / 10 || (rev == Integer.MAX_VALUE / 10 && pop > Integer.MAX_VALUE % 10)) return 0; if (rev < Integer.MIN_VALUE / 10 || (rev == Integer.MIN_VALUE / 10 && pop < Integer.MIN_VALUE % 10)) return 0;
rev = rev * 10 + pop; // 将 pop 添加到 rev 的最后 } return rev; // 返回反转后的整数 }}
运行效率也非常喜人,直接击败 100% 的 Java 提交者。
总结
这道题其实算不上中等的难度,不论是直接调用 reverse 还是通过取余和除法来获取每一位,都是比较容易想到的方法,唯一需要考虑的就是边界问题。
力扣链接:https://leetcode.cn/problems/reverse-integer/submissions/
学过基本数据类型的球友应该知道,Java 中的整数类型有 4 种,分别是 byte、short、int 和 long,它们的取值范围如下:
其中 int 类型的取值范围就是 32 位的有符号整数的取值范围,所以我们可以把 int 类型的最大值和最小值作为边界来判断是否溢出。
32 位的有符号整数的取值范围是从 -2^31 到 2^31 - 1,其中一位用于表示符号(正或负),剩下的 31 位用于表示数值,这意味着其范围是 -2,147,483,648(即 -2^31)到 2,147,483,647(即 2^31 - 1)。
在二进制系统中,每个位(bit)可以表示两个状态,通常是 0 和 1。对于 32 位得正二进制数,除去符号位,从右到左的每一位分别代表 2^0, 2^1, 2^2, ..., 2^30,这个二进制数转换为十进制就是 2^0 + 2^1 + 2^2 + ... + 2^30,也就是 2,147,483,647。
第一种题解很容易想到,涉及到的知识点有:
第二种题解也不难想到,主要就是除法和取余的运算,以及边界的判断,涉及到的知识点有:
一步一个脚印
不积跬步无以至千里,不积小流无以成江海。LeetCode - 100天从算法小白到卷王正式启动了,我们计划周一到周五至少每天更新一篇,周六周日更新一篇,目标 300 道 LeetCode 经典题。
该题解目前只针对**二哥编程星球 **的球友开放,如果你也想一起打卡学习算法的话,扫下面的优惠券加入我们吧,星球目前 4100+ 人,定价 149 元,从当初的 99 元一路涨上来的,所以早就是优势,别再犹豫了。
(优惠券仅 300 张,数量有限)
一个人可以走得很快,但一群人才能走得更远。如果想去面中大厂的话,LeetCode 几乎是必刷的,二哥的 LeetCode 题解通俗易懂、图文并茂,理解给你举一反三的解题能力,冲鸭。
- 语雀专栏地址+密码可通过星球置顶帖查看:[https://t.zsxq.com/15rEo9Pdu](https://t.zsxq.com/15rEo9Pdu)
-
技术派专栏地址:https://paicoding.com/column/7/ 7
-
这道题可以说完全重写了,给出两道大家完全都能掌握的题解,并且追加手绘图,大家会非常容易掌握,一道中等难度直接变身 easy 难度。
-
增加代码注释,这样大家更容易看懂并掌握题解;
-
增加参考资料,这样大家可以从零基础直接开刷,减轻新手刷题的阻力;
-
增加手绘图,这样大家更容易理解解题思路;
-
增加 ACM 输入输出,这样大家可以在 Intellij IDEA 中进行调试;
-
增加题解模拟,这样大家可以根据题解模拟整个题解过程,看完会有一种“哦哦”恍然大悟的感觉;
-
图片上传至 OSS 并配合 CDN,提升大家在技术派网站中的阅读体感。
-
另外,这一版本会作为 PDF 的终稿随后在星球进行发布。
二哥的 LeetCode 题解真的精辟——鲁迅(我没说)
题意
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例
输入:x=123
输入:x=-123输出:-321 输入:x=120输出:21 输入:x=0输出:0
难度
中等
分析 1
看到这题,我的第一感觉就是把 32 位的整数看成是一个字符串,然后直接调用 StringBuilder 的 reverse 方法,这样就可以完成反转了,对吧,完全可行。
剩下需要做的,就是处理一下负数的情况,还有超出边界的情况。
class Solution {
String reversed = new StringBuilder().append(Math.abs(x)).reverse().toString(); try { // 如果原始整数为负数,则反转后的结果也应该是负数 int result = Integer.parseInt(reversed); return (x < 0) ? result * -1 : result; } catch (NumberFormatException e) { // 捕获溢出异常并返回 0 return 0; } }}
①、Math.abs () 方法可以获取一个数的绝对值,比如Math.abs (-123)的结果就是123。
②、然后用 StringBuilder 的 append 方法将正数添加到字符串序列中。
③、调用 reverse 方法将字符串反转。我在《二哥的 Java 进阶之路》里曾讲过 reverse 方法 ,没看过源码的**球友 **可以回头看一眼。
int n = count - 1; // 字符序列的最后一个字符的索引
for (int j = (n-1) >> 1; j >= 0; j--) { int k = n - j; // 计算相对于 j 对称的字符的索引 char cj = value[j]; // 获取当前位置的字符 char ck = value[k]; // 获取对称位置的字符 value[j] = ck; // 交换字符 value[k] = cj; // 交换字符}
这个翻转的方法其实非常巧妙,从字符串的两端开始交换,直到中间位置,比从头到尾或者从尾到头要快一倍。
④、最后调用 Integer 的 parseInt 方法将字符串转换成整数,如果超出边界,就会抛出 NumberFormatException 异常 ,我们通过 try-catch 捕获这个异常,然后返回 0。如果是负数,就将结果乘以 -1。
来看一下题解的效率:
还不错,那其实我们可以再优化一下,不调用 StringBuilder 的 reverse 方法,我们可以自己实现一个翻转的方法,把 reverse 方法的源码拿过来改一改就行了。
class Solution {
String reversed = reverseString(String.valueOf(Math.abs(x))); try { // 如果原始整数为负数,则反转后的结果也应该是负数 int result = Integer.parseInt(reversed); return (x < 0) ? result * -1 : result; } catch (NumberFormatException e) { // 捕获溢出异常并返回 0 return 0; } }
private String reverseString(String s) { char[] value = s.toCharArray(); int n = value.length - 1; for (int j = (n-1) >> 1; j >= 0; j--) { int k = n - j; char cj = value[j]; char ck = value[k]; value[j] = ck; value[k] = cj; } return new String(value); }}
只不过,这样做的意义不大,换汤不换药而已,有没有更好的方法呢?
分析 2
对于一个整数来说,我们可以通过取余和除法来获取它的每一位,比如123,我们通过123 % 10来获取它的个位 3,123 / 10来把它的个位去掉,剩下 12;
然后通过12 % 10来获取它的十位 2,12 / 10来把它的十位去掉,剩下 1;
然后再通过1 % 10来获取它的百位 1,1 / 10来把它的百位去掉,剩下 0,这样就把整数的每一位都获取到了,获取知道就很好处理了,不断地乘以 10 累加就行了。
唯一需要注意的就是判断一下是否超出边界,这里我用了一个小技巧,就是在每次累加之前,先判断一下累加后的结果是否超出边界,如果超出边界,就直接返回 0,否则再累加。
class Solution {
int rev = 0; // 用于存储反转后的结果 while (x != 0) { int pop = x % 10; // 获取 x 的最后一位数字 x /= 10; // 移除 x 的最后一位数字
// 检查溢出:如果 rev > Integer.MAX_VALUE/10 或 rev < Integer.MIN_VALUE/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; // 将 pop 添加到 rev 的最后 } return rev; // 返回反转后的整数 }}
①、rev == Integer.MAX_VALUE / 10 && pop > 7
- Integer.MAX_VALUE 是 2147483647,Integer.MAX_VALUE / 10 则是 214748364。
- 当 rev 等于 214748364 时,乘以 10 再加上任何大于 7 的数字将导致整数溢出,比如说 214748364 * 10 + 8 = 2147483648 > Integer.MAX_VALUE(2147483647)。
②、rev == Integer.MIN_VALUE / 10 && pop < -8
- Integer.MIN_VALUE 是 -2147483648,Integer.MIN_VALUE / 10 则是 -214748364。
- 当 rev 等于 -214748364 时,乘以 10 再减去任何小于 -8 的数字将导致整数溢出,比如说 -214748364 * 10 - 9 = -2147483649 < Integer.MIN_VALUE(-2147483648)。
那如果说,写题解的时候,不想出现这种魔法数字(7 或者 -8),可以这样写:
class Solution {
int rev = 0; // 用于存储反转后的结果 while (x != 0) { int pop = x % 10; // 获取 x 的最后一位数字 x /= 10; // 移除 x 的最后一位数字
// 检查溢出:如果 rev > Integer.MAX_VALUE/10 或 rev < Integer.MIN_VALUE/10,则会溢出 if (rev > Integer.MAX_VALUE / 10 || (rev == Integer.MAX_VALUE / 10 && pop > Integer.MAX_VALUE % 10)) return 0; if (rev < Integer.MIN_VALUE / 10 || (rev == Integer.MIN_VALUE / 10 && pop < Integer.MIN_VALUE % 10)) return 0;
rev = rev * 10 + pop; // 将 pop 添加到 rev 的最后 } return rev; // 返回反转后的整数 }}
运行效率也非常喜人,直接击败 100% 的 Java 提交者。
总结
这道题其实算不上中等的难度,不论是直接调用 reverse 还是通过取余和除法来获取每一位,都是比较容易想到的方法,唯一需要考虑的就是边界问题。
力扣链接:https://leetcode.cn/problems/reverse-integer/submissions/
学过基本数据类型的球友应该知道,Java 中的整数类型有 4 种,分别是 byte、short、int 和 long,它们的取值范围如下:
其中 int 类型的取值范围就是 32 位的有符号整数的取值范围,所以我们可以把 int 类型的最大值和最小值作为边界来判断是否溢出。
32 位的有符号整数的取值范围是从 -2^31 到 2^31 - 1,其中一位用于表示符号(正或负),剩下的 31 位用于表示数值,这意味着其范围是 -2,147,483,648(即 -2^31)到 2,147,483,647(即 2^31 - 1)。
在二进制系统中,每个位(bit)可以表示两个状态,通常是 0 和 1。对于 32 位得正二进制数,除去符号位,从右到左的每一位分别代表 2^0, 2^1, 2^2, ..., 2^30,这个二进制数转换为十进制就是 2^0 + 2^1 + 2^2 + ... + 2^30,也就是 2,147,483,647。
第一种题解很容易想到,涉及到的知识点有:
第二种题解也不难想到,主要就是除法和取余的运算,以及边界的判断,涉及到的知识点有:
一步一个脚印
不积跬步无以至千里,不积小流无以成江海。LeetCode - 100天从算法小白到卷王正式启动了,我们计划周一到周五至少每天更新一篇,周六周日更新一篇,目标 300 道 LeetCode 经典题。
该题解目前只针对**二哥编程星球 **的球友开放,如果你也想一起打卡学习算法的话,扫下面的优惠券加入我们吧,星球目前 4100+ 人,定价 149 元,从当初的 99 元一路涨上来的,所以早就是优势,别再犹豫了。
(优惠券仅 300 张,数量有限)
一个人可以走得很快,但一群人才能走得更远。如果想去面中大厂的话,LeetCode 几乎是必刷的,二哥的 LeetCode 题解通俗易懂、图文并茂,理解给你举一反三的解题能力,冲鸭。
知识星球
扫码加入星球
查看更多优质内容
https://wx.zsxq.com/mweb/views/joingroup/join_group.html?group_id=15522885221412