7369 字
约 24 分钟
1
007.整数反转
无标签

007.整数反转

作者:沉默王二 发布时间:2023-12-28T14:36:09.406+0800


  • 语雀专栏地址+密码可通过星球置顶帖查看:https://t.zsxq.com/15rEo9Pdu

  • 技术派专栏地址:https://paicoding.com/column/7/ 7

  • 星球原地址:https://t.zsxq.com/15u5YkmHY

  • 这道题可以说完全重写了,给出两道大家完全都能掌握的题解,并且追加手绘图,大家会非常容易掌握,一道中等难度直接变身 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

  • 星球原地址:https://t.zsxq.com/15u5YkmHY

  • 这道题可以说完全重写了,给出两道大家完全都能掌握的题解,并且追加手绘图,大家会非常容易掌握,一道中等难度直接变身 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

  • 星球原地址:https://t.zsxq.com/15u5YkmHY

  • 这道题可以说完全重写了,给出两道大家完全都能掌握的题解,并且追加手绘图,大家会非常容易掌握,一道中等难度直接变身 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
007.整数反转
http://www.clxhxhhr.top/posts/2432/
作者
clxstart
发布于
2026-09-19
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。
文章目录