详解 LeetCode_007_整数反转(Java 实现)
LeetCode_007_整数反转
题目描述
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。 示例 1: 输入: 123 输出: 321 示例 2: 输入: -123 输出: -321 示例 3: 输入: 120 输出: 21 注意: 假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−2^31, 2^31 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/reverse-integer 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
总体分析
题目中要求将一个有符号整数进行反转,通过题目给出的例子,需要注意以下几点:
整数会有负数的情况,反转后符号不变。
只能存储 32 位有符号整数,取值范围为:-2147483648 ~ 2147483647。超过此范围即为溢出。如果反转后发生了溢出情况,返回 0。
要反转的数字最后一位是 0 的情况反转过来后要将 0 舍弃。
-
如题目中的这个例子:120 --> 21。
解决方案
思路分析: 首先,先分析溢出问题,对于题目中要求的 32 位有符号整数,其实也就是 int 类型,相对应的取值范围为:-2147483648 ~ 2147483647。那么发生溢出的情况就是反转过来的数不在这个范围内。
举个例子:将 2111222239 反转过来后为 9322221112,此时这个数超过了上面的范围,这个情况就是溢出,此时返回 0 即可。
接着,分析转换的数是负数时的情况:如果要转换的数是负数,就先取其绝对值将其反转后再将结果转换为负数返回即可。
综上,可以设计解题流程如下,假设要转换的数为 x:
首先判断 x 是否为 -2147483648,如果是返回 0,防止取 x 绝对值 -x 时报错。
判断 x 是否为负数,如果是负数则先取其绝对值然后递归取反,最后将结果转换为负数。
使用一个变量 result 保存结果,初始时为 0。
对 x 取反时将 x % 10 依次取出最后一位数(例如: 256 % 10 = 6)放置到 result 中(即 result * 10 + x % 10),最后将 x / 10。依次进行此过程即可将 x 反转。
在取反过程中需要注意的是要进行该判断:if (result > 214748364) 进行提前判断溢出处理。
举个例子说明:
1463847412 反转后为 2147483641,此时当反转到 214748364 时,还没有大于,所以没有溢出。如果 result > 214748364 说明反转后就已经溢出了。
例如:1563847412 -> 2147483651,当反转到 214748365 时,由于大于了 214748364,所以可以提前判断溢出。
判断 result 是否溢出,如果溢出返回 0,否则返回反转后的结果,这里判断溢出是因为前面的提前判断溢出不能判断到最后一位,如果最后一位加的数超过溢出值的话就会产生溢出,所以需要判断。不好理解的话可以结合下面代码进行理解。
根据以上思路,可设计题解代码如下:
/** * 整数反转解题方案 * * @author 踏雪彡寻梅 * @date 2020/2/6 - 12:14 */ class Solution { public int reverse(int x) { if (x == -2147483648) { // 做此判断防止取 x 绝对值时 x = -x 报错 return 0; } if (x < 0) { // 如果为负数,取其绝对值调用自己然后将结果转为负数 return -reverse(-x); } // 用于保存结果返回 int result = 0; // 取反操作 while (x != 0) { if (result > 214748364) { // 处理溢出 // 举例:1463847412 // 反转后:2147483641 // 此时当反转到 214748364 时,还没有大于,所以没有溢出 // 如果 result > 214748364 反转后就已经溢出了 // 例如:1563847412 -> 2147483651 // 当反转到 214748365 时,由于大于了 214748364,所以可以提前判断溢出 return 0; } // 接收取反结果 result = result * 10 + x % 10; x /= 10; } // 如果溢出就返回 0 // 防止提前判断溢出不能判断到最后一位的情况,如果最后一位加的数超过溢出值的话就会产生溢出 return result <= 2147483647 ? result : 0; } }
提交结果:
提交后时间上和空间上的结果还是效果蛮好的O(∩_∩)O。接下来进行一些简单的时间复杂度和空间复杂度分析。
时间复杂度简单分析: 对于时间复杂度则是分析 while 循环中的代码,因为这块代码占据了程序的时间是最多的。
while (x != 0) { if (result > 214748364) { return 0; } result = result * 10 + x % 10; x /= 10; }
从以上代码可以看出,x 每循环一次就除以 10,直到 x = 0 时或者 result 溢出时才结束循环。这里假设 result 不溢出的情况来进行分析:
对于 x / 10 判断 x 是否等于 0 其实可以看为:x 除了几次 10 才等于 0。这里假设这个次数为 n。
用式子表达也就是:x / 10 / 10 / 10 / ... / 10 = x / 10n = 0,即可以表示为 x = 10n
也就是说明,程序的运行时间主要跟 n 相关,所以需要将 n 计算出来:
通过 x = 10n 求解 n 这个问题在高中时就已经学过了,即 n = log10x。
所以,时间复杂度为 O(log10x) = O(lgx)。
空间复杂度简单分析: 空间上使用了一个 result 整型变量用来辅助接收结果,每次赋值分配的空间都是常数级别的,所以空间复杂度为 O(1)。
小结
解题时需要注意特殊情况:为负数的情况、尾部为 0 的情况以及整数溢出的情况。 如有写的不足的,请见谅,请大家多多指教。
- leetcode-7 整数反转 java实现
- 【LeetCode-面试算法经典-Java实现】【007-Reverse Integer(翻转整数)】
- Java&LeetCode 初入门——007. 整数反转
- 【leetcode】Reverse Integer整数反转----Java代码实现
- 【LeetCode-面试算法经典-Java实现】【029-Divide Two Integers(两个整数相除)】
- 【LeetCode-面试算法经典-Java实现】【008-String to Integer (atoi) (字符串转成整数)】
- 【LeetCode-面试算法经典-Java实现】【206-Reverse Linked List(反转一个单链表)】
- LeetCode 7. 整数反转 (Java)
- [leetcode 7] Reverse Integer(整数反转) c函数实现
- 【Leetcode刷题】007.整数反转
- leetcode的python实现 刷题笔记7: 反转整数
- Leetcode题库-整数反转(java语言版)
- Java实现-反转整数
- 【LeetCode-面试算法经典-Java实现】【025-Reverse Nodes in k-Group(单链表中k个结点一组进行反转)】
- leetcode 7. 整数反转(Java版)
- python实现leetcode-第七题-整数反转
- LeetCode 罗马数字转整数(Java实现)
- 【LeetCode-面试算法经典-Java实现】【013-Roman to Integer (罗马数字转成整数)】
- 【LeetCode-面试算法经典-Java实现】【092-Reverse Linked List II(反转单链表II)】
- 【LeetCode-cpp】【65】007. 简单 整数反转 Reverse Interger