一、LeetCode 7. 整数反转
题目介绍:
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 −1][−2^{31}, 2^{31} − 1][−231,231−1] ,就返回 000。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例:
输入: x = 123 输出: 321
输入: x = -123 输出: -321
二、解题分析
很多同学看到这个问题的时候,感觉很容易。判断下是否有符号,然后将整数x
进行字符串翻转,拼接对应的符号位。
但是要注意题目里面的要求“假设环境不允许存储 64 位整数(有符号或无符号)
”,同时在使用字符串翻转的形式会导致溢出问题。
大家可以手动尝试下~
尝试从另外一个角度来看,以“个十百千万”来看,每一位数都是都是十进制内的数,同时是满十进一。
假定使用变量rev
来存储结果,初始值设置为0
- 我们可以对变量
x
进行取余,拿到当前最后一位数diget
,变量rev
的值为rev * 10 + diget
;
- 对变量
x
取余后,将剩下的数取整,再次进行取余,获取当前的最后一位数,再次赋值给rev
;
- 循环上述操作,终止循环的操作是变量
x
的值为0时;
- 对最大值和最小值的临界判断 [−231, 231 −1][−2^{31}, 2^{31} − 1][−231,231−1] ,返回000
上代码
/** * @param {number} x * @return {number} */ var reverse = function(x) { let rev = 0; while (x !== 0) { // 获取每一次的最后一位数 const digit = x % 10; // 这里要特别注意:不是向下取整,因为有可能x是负数, // Math.floor(-12.3)取整时,返回的是-13,但实际上我们需要的是-12 // ~~双非按位取反运算符,对于正数,向下取整;对于负数,向上取整 x = ~~(x/10); rev = rev * 10 + digit; // 临界值判断 if (rev < Math.pow(-2, 31) || rev > Math.pow(2, 31) - 1) { return 0; } } return rev; };
提交代码,查看下效果,通过全部Case。
网络异常,图片无法展示
|
三、总结
- 整数翻转这个问题,主要是在限制条件范围内(不允许使用存储64位整数,无论是有符号还是无符号),做出翻转;
- 在数学运算中,十进制数字对十进行取余操作,可以获取最后一位数字;
- 按位运算法
~~
的妙用,还有些其他按位运算,大家可以多多尝试
算法-从菜鸟开始,而无止境。与君共勉!