题目:给你一个 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方法对字符数组进行转换,同时判断其有效范围,并输出结果,具体代码如下:
02、int类型字符串转换法
既然题目中要求我们不能使用64位整数long类型,那么我们是否可以直接int类型进行转换呢?
根据上一个解法,同样的思路,我们先把int整数x转为字符串,然后直接使用int.TryParse进行转换即可。这样可以利用转换失败过滤掉所有溢出的值。
具体实现代码如下:
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,因此只需要判断第九位数字是否合法即可完成溢出判断。
具体实现代码如下:
04、基准测试
我们做个简单的基准测试,分别对三种方法进行100万次随机生成整数值在范围-2147483648至2147483647之间的值进行测试,得到如下结果。
通过上图不难发现数学方法在整体性能方面远远高于字符串处理方式。
热门跟贴