题目:给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。如果反转后整数超过 32 位的有符号整数的范围 [−231,  231 − 1] ,就返回 0。

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

01、long类型字符串转换法

虽然题目要求不允许使用64位整数,但是我们还是先使用最简单最直观的最符合思维逻辑的方式实现,然后以此打开思维寻找出更好的方法。

看到此题我第一反应就是直接把整数x转为字符串,然后直接调用字符串方法反转字符串,最后把反转后的字符串转换为long类型,同时比较是否再有效范围内即可。

当然这是大致解题思路,其中还有许多细节需要处理。

首先需要处理负号问题,如果是负数我们需要取其绝对值,然后再反转绝对值,而在取绝对值时需要注意int的最小值int.MinValue为-2147483648,而int.MaxValue最大值为2147483647,因此我们不能直接对int整数x直接取绝对值,而需要先把x转为long类型整数,不然会报错。

然后把绝对值反转成字符数组,同时判断正负号,如果是负数则需要在字符数组前加上负号’-’。

最后直接使用long.TryParse方法对字符数组进行转换,同时判断其有效范围,并输出结果,具体代码如下:

//字符串long
public static int ReverseLongString(int x)
{
//是否为负数
var isNegative = x < 0;
//取绝对值,必须要先转为long类型
//否则int.MinValue -2147483648会报错
var abs = Math.Abs((long)x);
//把值转为字符串并反转,得到字符集合
var reversedChars = abs.ToString().Reverse();
if (isNegative)
{
//如果是负数则在字节数组前加入负号'-'
reversedChars = reversedChars.Prepend('-');
}
//转换为long类型,并且是有效的int值,则返回结果
if (long.TryParse(reversedChars.ToArray(), out long result) && result >= int.MinValue && result <= int.MaxValue)
{
return (int)result;
}
return 0;
}

02、int类型字符串转换法

既然题目中要求我们不能使用64位整数long类型,那么我们是否可以直接int类型进行转换呢?

根据上一个解法,同样的思路,我们先把int整数x转为字符串,然后直接使用int.TryParse进行转换即可。这样可以利用转换失败过滤掉所有溢出的值。

具体实现代码如下:

//字符串int
public static int ReverseIntString(int x)
{
//把值转为字符串,并去掉负号'-',最后反转,得到字符集合
var reversed = x.ToString().TrimStart('-').Reverse();
//转换为int,成功则返回
if (int.TryParse(reversed.ToArray(), out int result))
{
//根据原始符号,返回结果
return x < 0 ? -result : result;
}
return 0;
}

03、数学方法

上面两个方法本质还是通过字符串转换,就效率来说是比较低的,因此我们可以通过数学计算的方式来实现其转换。

如上图,我们以把12345反转为例,详解讲解反转过程。

(1)通过12345%10,获取到尾数字5,而尾数字又将作为新数值的首数字,新数值5;

(2)通过1234%10,获取到尾数字4,新数值为5*10+4=54;

(3)通过123%10,获取到尾数字3,新数值为54*10+3=543;

(4)通过12%10,获取到尾数字2,新数值为543*10+2=5432;

(5)通过1%10,获取到尾数字1,新数值为5432*10+1=54321;

其中还有一个重点是关于溢出的判断,前两个方法本质都是通过转换方法触发异常来拦截溢出,而在此方法中我们可以在实时计算的过程中直接判断出是否溢出。

因为32位有符号整数x的取值范围是-2147483648<=x<=2147483647,如果要保证反转过来不溢出,则在处理到第九位的时候整个值应该在(-214748364,214748364)之间,不然结果肯定会溢出,而有效的int值首位数字最大为2,即使反转过来也不可能大于7或小于-8,因此只需要判断第九位数字是否合法即可完成溢出判断。

具体实现代码如下:

//数学方法
public static int ReverseMath(int x)
{
var result = 0;
while (x != 0)
{
//判断溢出,因为输入的是32位的有符号整数 x
//即输入的 -2147483648<=x<=2147483647
//所以翻转后的最后一位是1或2并不会导致溢出
//因此只需判断九位数 > int.MaxValue / 10 或者 < int.MinValue / 10
if (result < int.MinValue / 10 || result > int.MaxValue / 10)
{
return 0;
}
//获取当前末尾的数字
var digit = x % 10;
//去掉末尾数字
x /= 10;
//反转并累积结果
result = result * 10 + digit;
}
return result;
}

04、基准测试

我们做个简单的基准测试,分别对三种方法进行100万次随机生成整数值在范围-2147483648至2147483647之间的值进行测试,得到如下结果。

通过上图不难发现数学方法在整体性能方面远远高于字符串处理方式。

:测试方法代码以及示例源码都已经上传至代码库,有兴趣的可以看看。https://gitee.com/hugogoos/Planner

LeetCode题集-7 - 整数反转的更多相关文章

  1. 【LeetCode】Reverse Integer(整数反转)

    这道题是LeetCode里的第7道题. 题目描述: 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 1: 输入: 123 输出: 321  示例 2: 输入: -123 ...

  2. Leetcode(7)整数反转

    Leetcode(6)Z字形变换 [题目表述]: 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 第一次:转字符串处理 执行用时:40 ms: 内存消耗:11.6MB 效果: ...

  3. [LeetCode]7. Reverse Integer整数反转

    Given a 32-bit signed integer, reverse digits of an integer. Example 1: Input: 123 Output: 321 Examp ...

  4. leetcode 题集

    775. Global and Local Inversions 统计相邻元素组成的逆序对(local inversion)和全局逆序对的数量(global inversion) 思路:local i ...

  5. Leetcode题库——12.整数转罗马数字

    @author: ZZQ @software: PyCharm @file: intToRoman.py @time: 2018/9/28 21:59 要求: 字符 数值 I 1 V 5 X 10 L ...

  6. Leetcode7_整数反转

    题目 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 1: 输入: 123输出: 321 示例 2: 输入: -123输出: -321 示例 3: 输入: 120输出: ...

  7. Leetcode题库——7.反转整数

    @author: ZZQ @software: PyCharm @file: IntReverse.py @time: 2018/9/16 16:36 要求:整数反转(给定一个 32 位有符号整数,将 ...

  8. Leetcode(力扣) 整数反转

    Leetcode 7.整数反转 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例: 输入: -123 输出: -321 注意: 假设我们的环境只能存储得下 32 位的有符 ...

  9. Newtonsoft.Json C# Json序列化和反序列化工具的使用、类型方法大全 C# 算法题系列(二) 各位相加、整数反转、回文数、罗马数字转整数 C# 算法题系列(一) 两数之和、无重复字符的最长子串 DateTime Tips c#发送邮件,可发送多个附件 MVC图片上传详解

    Newtonsoft.Json C# Json序列化和反序列化工具的使用.类型方法大全   Newtonsoft.Json Newtonsoft.Json 是.Net平台操作Json的工具,他的介绍就 ...

  10. C# 算法题系列(二) 各位相加、整数反转、回文数、罗马数字转整数

    各位相加 给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数. 示例: 输入: 输出: 解释: 各位相加的过程为: + = , + = . 由于 是一位数,所以返回 . 进阶:你可以 ...

随机推荐

  1. C语言位域的内存布局

    本文将先粗略介绍大小端,和大小端的测试方法,最后介绍位域的内存布局. 1. 大小端 大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中. 小端模式,是指数据的高字节保存 ...

  2. .net6 使用gRPC示例

    创建一个gRPC服务项目(grpc服务端)和一个 webapi项目(客户端),测试项目结构如下: 公共模型 测试接口相关类,放在公共类库中,方便服务端和客户端引用相同模型 public class R ...

  3. 29. GIL全局解释器锁、信号量、线程池进程池

    1. GIL全局解释器锁 1.1 概念 '''In CPython, the global interpreter lock, or GIL, is a mutex that prevents mul ...

  4. .Net 中 LINQ 基础

    LINQ 基本概念: 语句集成查询,(Language - Integrated Query) 常见用途: .Net 原生集合(List,Array,Dictonary,etc) SQL数据库(尤其是 ...

  5. ssh建立github连接 基于ssh密钥

    1. 建立公钥和私钥 ps:公钥放在github上面的,私钥放在自己本地电脑 : 先生成密钥:打开 gitbash 输入命令: ssh-keygen -t rsa -b 4096 -C "z ...

  6. npm/yarn是什么,他们的区别 ? & node.js 又是个啥

    是什么? npm(全称Node Package Manager,即 node 包管理器) ,是Node.js默认的包管理系统 ; 区别: yarn 的速度开快,因为yarn 是并行安装,npm是串行安 ...

  7. 让查询可以使用 json path

    记录一下最近sv.db的完善 1. 让查询可以使用 json path 有时候我们会存储 json 到 db,也有时会只取json部分数据,或者通过json部分数据进行过滤 所以sv.db 也支持这些 ...

  8. 5.15 相约上海!2021 年度首届云原生 Meetup | KubeSphere & Friends

    时至今日,Kubernetes 虽然变成了云原生这套系统化方法论和开源技术的核心一环,但已经无法独立存在,而是与云原生生态中所有的技术形态息息相关.为了将云原生生态中的各个技术形态结合起来,帮助企业最 ...

  9. 云原生爱好者周刊:寻找 Netlify 开源替代品

    开源项目推荐 Coolify Coolify 是一个开源自托管的 Heroku/Netlify 替代品,颜值还不错. Podman Desktop Podman Desktop 是针对 Podman ...

  10. Java中List 删除元素

    在Java中,使用List时想要删除某个特定个元素怎么办?很好办!因为List接口有remove()这个方法,我们只需要调用remove()方法,就可以删除list中的某个元素.但是list自带的有一 ...