整数反转Java_LeetCode刷题之旅【简单篇】——7.整数反转

给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

Given a 32-bit signed integer, reverse digits of an integer.

示例 1:

输入:123

输出: 321

示例 2:

输入: -123

输出: -321

示例 3:

输入: 120

输出: 21

个人思路

首先需要说明,中文题目会引起人的误会,32位有符号整数,容易理解成是十进制下的32位;而从英文题目看,32位指的是二进制中的32位,也就是int类型。

方案1:

从目前的观察来看,可以将输入int数字转换成字符串后直接反向输出,需要考虑的是以下几个特例:

负数:负数的符号需要特殊处理

末尾为0的情况:末尾为0的数字倒序输出时在开头,不需要输出(使用Java自带的函数这点可以不考虑)

尤其需要注意的是,翻转越界的问题:如果输入为1534236469,翻转后为9646324351,会超出int的取值范围[-2,147,483,648, 2,147,483,647],这时Java会抛出异常,我们只要捕获这个异常,并且在有异常时返回0即可。

下面是实现代码:

class Solution {

public int reverse(int x) {

String xstr = String.valueOf(x);

String nstr = new String();

for (int i = xstr.length(); i > 0; i--){

if("-".charAt(0)==xstr.charAt(i-1)){

nstr = xstr.charAt(i-1) + nstr;

} else{

nstr = nstr + xstr.charAt(i-1);

}

}

int result = 0;

try{

result = Integer.parseInt(nstr);

} catch (Exception e){

}

return result;

}

}

运行结果:

执行用时 :19 ms, 在所有 Java 提交中击败了5.52%的用户

内存消耗 :38.3 MB, 在所有 Java 提交中击败了5.33%的用户

目前来看,这个方法想着比较简单,但实现起来代码还是挺多的,而且事实上速度较慢,占用内存也较多,放在这里,希望能有抛砖引玉的作用。

方案2:

前面想要投机取巧似乎不是个好的方案,那还有一个方案就是通过取余,取出每一位的值,如果而后再计算组合成翻转后的数字。

详细可以参考讨论区中的这个解释,图片解释得很清楚。

很容易可以写出如下的代码:

class Solution {

public int reverse(int x) {

int result = 0;

while(x != 0){

result = result * 10 + x % 10;

x = x / 10;

}

return result;

}

}

其实这个题目一个小小的难点是如何控制越界;首先,要复习下,Java中int的最大最小值存储在Integer.MAX_VALUE和Integer.MIN_VALUE中;其次,在计算result的过程中,如果result值越界,不会有任何异常抛出,因此必须在计算前对越界这个情况进行检查。

如果我们记最大值为$maxValue$,最小值为$minValue$,计算前result的值为$r$,x的末尾为$xTail$,那么有:

$r*10+xTail

$r*10+xTail>minValue$

继而:

$r < (maxValue - xTail) / 10$

$r > (minValue - xTail) / 10$

如果我们把右边拆开,则有:

$r < maxValue / 10 - xTail / 10$

$r > minValue / 10 - xTail / 10$

这样不就OK了吗,于是有了下面的代码:

class Solution {

public int reverse(int x) {

int result = 0;

while(x!=0){

if(result > (Integer.MAX_VALUE-x%10)/10)

return 0;

if(result < (Integer.MIN_VALUE-x%10)/10)

return 0;

result = result * 10 + x % 10;

x = x / 10;

}

return result;

}

}

这样仍旧会wrong answer。这里值得注意的是,如果x为负数,那么while循环中第一个条件计算结果会溢出;而如果x为正数,那么第二个条件计算结果会溢出;所以不论什么值,都会返回0,修改后:

class Solution {

public int reverse(int x) {

int result = 0;

while(x!=0){

if(x > 0 && result > (Integer.MAX_VALUE-x%10)/10)

return 0;

if(x < 0 && result < (Integer.MIN_VALUE-x%10)/10)

return 0;

result = result * 10 + x % 10;

x = x / 10;

}

return result;

}

}

运行结果:

执行用时 :1 ms, 在所有 Java 提交中击败了100.00%的用户

内存消耗 :36.8 MB, 在所有 Java 提交中击败了5.33%的用户

官方解法

详见链接

class Solution {

public int reverse(int x) {

int rev = 0;

while (x != 0) {

int pop = x % 10;

x /= 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;

}

return rev;

}

}

不太一样的地方在于对溢出边界的控制,按照我们前面的记法,

$r*10+xTail

$r*10+xTail>minValue$

那么:

$r\geq maxValue/10$

$r\leq minValue/10$

对于$r\geq maxValue/10$,我们有:

$r = maxValue/10$时,如果$xTail > 7$,则计算结果溢出;

$r > maxValue/10$时,计算结果溢出。

同理对于$r\leq minValue/10$,也有:

$r = minValue/10$时,如果$xTail < -8$,则计算结果溢出;

$r < minValue/10$时,计算结果溢出。

于是有了上面的代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值