LeetCode 7 整数反转

题目描述

整数反转

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围 [−2^31, 2^31 − 1] ,就返回 0。

假设环境不允许存储 64 位整数(有符号或无符号)。

示例 1:

输入:x = 123
输出:321

示例 2:

输入:x = -123
输出:-321

示例 3:

输入:x = 120
输出:21

示例 4:

输入:x = 0
输出:0

提示:

  • -2^31 <= x <= 2^31 - 1

解法

  1. 转字符串反转

转为字符串后从后往前遍历反转

java代码

java 复制代码
public int revers(int x) {
    String s = String.valueOf(x);
    // 如果第一个是-,则删除,标记有横杠
    boolean hasHyphen = false;
    if (s.charAt(0) == 45) {
      s = s.substring(1);
      hasHyphen = true;
    }

    StringBuilder resBuilder = new StringBuilder();

    // 注意点:1.末尾的0去掉,中间的0保留;2.如果会死负数,把-去掉;2.-2147483648超过了范围,返回0
    // 最后一位是否是0,如果是0,把末尾的0都去掉,遇到第一个非0后,不再去掉0;不是0,则不需要去0
    boolean deleteZero = s.charAt(s.length() - 1) == 48;
    for (int i = s.length() - 1; i > -1; i--) {
      // 如果需要删除0并且遇到了非0,则后面就不再去掉0
      if (deleteZero && s.charAt(i) != 48) {
        deleteZero = false;
      }
      // 如果是0并且需要删除0,则略过
      if (s.charAt(i) == 48 && deleteZero) {
        continue;
      }

      resBuilder.append(s.charAt(i));

    }
    String resString = resBuilder.toString();

    // 判断是否超过范围:负数的话不超过2147483648,整数的话不超过2147483647
    if ((hasHyphen && (resString.length() > 10 || (resString.length() == 10 && resString.compareTo("2147483648") > 0)))
        || (!hasHyphen && (resString.length() > 10 || (resString.length() ==  10 && resString.compareTo("2147483647") > 0)))) {
      return 0;
    }

    int res = "".equals(resString) ? 0 : Integer.parseInt(resString);
    return hasHyphen ? -res: res;
}
  1. 官方解法:数学方法

记rev为翻转后的数字,为完成翻转,我们可以重复「弹出」x 的末尾数字,将其「推入」rev 的末尾,直至 x 为 0。

要在没有辅助栈或数组的帮助下「弹出」和「推入」数字,我们可以使用如下数学方法:

java 复制代码
// 弹出 x 的末尾数字 digit
digit = x % 10
x /= 10

// 将数字 digit 推入 rev 末尾
rev = rev * 10 + digit

题目需要判断反转后的数字是否超过 323232 位有符号整数的范围 [ − 2 31 , 2 31 − 1 ] [-2^{31},2^{31}-1] [−231,231−1]。例如 x = 2123456789 x=2123456789 x=2123456789反转后的 r e v = 9876543212 > 2 31 − 1 = 2147483647 {rev}=9876543212>2^{31}-1=2147483647 rev=9876543212>231−1=2147483647,超过了 323232 位有符号整数的范围。

因此我们需要在「推入」数字之前,判断是否满足:

− 2 31 ≤ r e v ⋅ 10 + d i g i t ≤ 2 31 − 1 -2^{31}≤rev⋅10+digit≤2^{31}-1 −231≤rev⋅10+digit≤231−1

若该不等式不成立则返回 0。

但是题目要求不允许使用 646464 位整数,即运算过程中的数字必须在 323232 位有符号整数的范围内,因此我们不能直接按照上述式子计算,需要另寻他路。

考虑 x>0的情况,记 I N T _ M A X = 2 31 − 1 = 2147483647 {INT\_MAX}=2^{31}-1=2147483647 INT_MAX=231−1=2147483647,由于

则不等式

r e v ⋅ 10 + d i g i t ≤ I N T M A X rev⋅10+digit≤INT_MAX rev⋅10+digit≤INTMAX

等价于

移项得

讨论该不等式成立的条件:

注意到当相等时若还能推入数字,则说明 x 的位数与 INT_MAX的位数相同,且要推入的数字 digit 为 x 的最高位。由于 x 不超过 INT_MAX,因此 digit 不会超过 INT_MAX 的最高位,即 digit≤2。所以实际上当 相等时不等式必定成立。

因此判定条件可简化为:当且仅当小于等于时,就成立。

x<0 的情况类似。

综上所述,判断不等式

− 2 31 ≤ r e v ⋅ 10 + d i g i t ≤ 2 31 − 1 -2^{31}≤rev⋅10+digit≤2^{31}-1 −231≤rev⋅10+digit≤231−1

是否成立,可改为判断不等式

I N T M I N / 10 < = r e v < = I N T M A X / 10 INT_MIN / 10 <= rev <= INT_MAX / 10 INTMIN/10<=rev<=INTMAX/10

java代码:

java 复制代码
class Solution {
    public int reverse(int x) {
        int rev = 0;  // 结果数字
        while (x != 0) {
            if (rev < Integer.MIN_VALUE / 10 || rev > Integer.MAX_VALUE / 10) {
                return 0;
            }
            // 取余数
            int digit = x % 10;
            // 原数字除以10后,得到的商为下一位数字
            x /= 10;
            // 原来的rev*10等于向高位移动一位,再加上余数,就是新数字
            rev = rev * 10 + digit;
        }
        return rev;
    }
}
相关推荐
微信-since8119215 分钟前
[ruby on rails] 安装docker
后端·docker·ruby on rails
肥猪猪爸17 分钟前
使用卡尔曼滤波器估计pybullet中的机器人位置
数据结构·人工智能·python·算法·机器人·卡尔曼滤波·pybullet
readmancynn29 分钟前
二分基本实现
数据结构·算法
萝卜兽编程31 分钟前
优先级队列
c++·算法
盼海39 分钟前
排序算法(四)--快速排序
数据结构·算法·排序算法
一直学习永不止步1 小时前
LeetCode题练习与总结:最长回文串--409
java·数据结构·算法·leetcode·字符串·贪心·哈希表
Rstln2 小时前
【DP】个人练习-Leetcode-2019. The Score of Students Solving Math Expression
算法·leetcode·职场和发展
芜湖_2 小时前
【山大909算法题】2014-T1
算法·c·单链表
珹洺2 小时前
C语言数据结构——详细讲解 双链表
c语言·开发语言·网络·数据结构·c++·算法·leetcode
代码吐槽菌2 小时前
基于SSM的毕业论文管理系统【附源码】
java·开发语言·数据库·后端·ssm