题解 | #反转数字#
反转数字
http://www.nowcoder.com/practice/1a3de8b83d12437aa05694b90e02f47a
算法思想一:直接法
解题思路:
1、如果数字 x 在【-10,10】之间则直接返回 x,因为一个数字反转之后还是其本身
2、将数字 x 转换为字符串 str_x
3、根据 字符串 str_x 首位判断该数字是正数还是负数
1、字符串 str_x[0] == '-',为负数,则对字符串(去除首位符号)反转 str_x = str_x[:0:-1],反转之后转为数字(负数)
2、当为正数时,直接对字符串进行反转 str_x = str_x[::-1],再转换为数字
4、判断反转后的数字是否在 [-2^31, 2^31-1]区间内,若在区间内则直接返回反转后的数字,否则返回0
代码展示:
Python版本
class Solution: def reverse(self , x ): # write code here if -10 < x < 10: return x str_x = str(x) # 区分正负数 if str_x[0] != "-": str_x = str_x[::-1] x = int(str_x) else: str_x = str_x[:0:-1] x = int(str_x) x = -x # 判断反转后的数字是否越界 return x if -2147483648 < x < 2147483647 else 0
复杂度分析
时间复杂度O(N):N表示数字的位数,需要遍历反转
空间复杂度O(N):数字转为字符串占用空间
算法思想二:数学法
解题思路:
1、通过循环将数字 x 的每一位拆开,在计算新值时每一步都判断是否溢出。2、溢出条件有两个,一个是大于整数最大值MAX_VALUE,另一个是小于整数最小值MIN_VALUE,设当前计算结果为ans,下一位为pop。
3、从ans * 10 + pop > MAX_VALUE这个溢出条件来看
1、当出现 ans > MAX_VALUE / 10 且 还有pop需要添加 时,则一定溢出
2、当出现 ans == MAX_VALUE / 10 且 pop > 7 时,则一定溢出,7是2^31 - 1的个位数
4、从ans * 10 + pop < MIN_VALUE这个溢出条件来看
1、当出现 ans < MIN_VALUE / 10 且 还有pop需要添加 时,则一定溢出
2、当出现 ans == MIN_VALUE / 10 且 pop < -8 时,则一定溢出,8是-2^31的个位数
上图绿色的是最大32位整数
第二排数字中,橘子的是5,它是大于上面同位置的4,这就意味着5后跟任何数字,都会比最大32为整数都大。
所以,我们到【最大数的1/10】时,就要开始判断了
如果某个数字大于 214748364那后面就不用再判断了,肯定溢出了。
如果某个数字等于 214748364呢,这对应到上图中第三、第四、第五排的数字,需要要跟最大数的末尾数字比较,如果这个数字比7还大,说明溢出了
第二排数字中,橘子的是5,它是大于上面同位置的4,这就意味着5后跟任何数字,都会比最大32为整数都大。
所以,我们到【最大数的1/10】时,就要开始判断了
如果某个数字大于 214748364那后面就不用再判断了,肯定溢出了。
如果某个数字等于 214748364呢,这对应到上图中第三、第四、第五排的数字,需要要跟最大数的末尾数字比较,如果这个数字比7还大,说明溢出了
上图中绿色部分是最小的32位整数,同样是在【最小数的 1/10】时开始判断
如果某个数字小于 -214748364说明溢出了
如果某个数字等于 -214748364,还需要跟最小数的末尾比较,即看它是否小于8
如果某个数字小于 -214748364说明溢出了
如果某个数字等于 -214748364,还需要跟最小数的末尾比较,即看它是否小于8
代码展示:
JAVA版本
import java.util.*; public class Solution { /** * * @param x int整型 * @return int整型 */ public int reverse (int x) { // write code here int ans = 0; while (x != 0) { int pop = x % 10; if (ans > Integer.MAX_VALUE / 10 || (ans == Integer.MAX_VALUE / 10 && pop > 7)) return 0; if (ans < Integer.MIN_VALUE / 10 || (ans == Integer.MIN_VALUE / 10 && pop < -8)) return 0; ans = ans * 10 + pop; x /= 10; } return ans; } }
复杂度分析
时间复杂度O(N):N表示数字的位数,需要遍历反转
空间复杂度O(1):常数级空间