7、整数反转-leetcode

题目描述:

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

  • 示例1:
输入:123
输出:321
  • 示例2:
输入:-123
输出:-321
  • 示例3:
输入:120
输出:21
  • ** 注意:**假定我们的环境只能存储得下32位的有符号的整数,则其数值的范围是[-231, 231-1]。请根据这个假设,如果反转后的整数溢出那么就返回0。

  • 算法设计分析:

如果使用Python3进行解题,方法的使用还是很灵活的,下面提供一种方法:
1、首先是需要进行负数的处理:可以设置一个标志,mark=1时表示正数,mark=-1时候表示负数,其中当传入的整数是负数的时候,先对负数转化成为正数,同时设置标志为mark=-1。
2、其次将整数进行反转:将x整数转化成为字符串使用str()->将字符串转换成为列表list()->对列表的所有元素进行反转[::-1]->对于反转后的字符串进行遍历->为确保列表的元素遍历之后都是字符串使用str()单个进行处理->将遍历出来的字符串逐个合成一整块字符串使用join() -> 将转成一块的字符串转换成为正数int() ->还原该整数的正负值
3、最后对整数的范围进行限制检查,不通过返回0,通过返回该整数。

  • Python3解法:
class Solution:
    def reverse(self, x: int) -> int:
        # 处理前面的符号情况
        mark = 1
        if x < 0:
            x = -x
            mark = -1
        # a[::-1]) ### 取从后向前(相反)的元素:反转
        reverseInt = int(''.join(str(i) for i in list(str(x))[::-1])) * mark
        if reverseInt < (-2**31) or reverseInt > (2**31-1):
            return 0
        return reverseInt
  • java解法
  • 算法的设计与分析:

本题的解答可以使用数学的基本知识来进行求解
如果不考虑溢出的问题,可以简单的解答出来。这里有两个解答思路:一个思路是通过字符串转换加try catch的方式来解决,第二个思路就是通过数学计算来进行解决
这里使用数据计算的方式来进行解决。
首先通过循环将数字x的每一位拆开,在计算新的值是时每一步都判断是否会溢出。
溢出的条件有两个,一个是大于整数最大值MAX_VALUE,另外一个是小于整数的最小值MIN_VALUE,设当前的计算结果为ans,下一位为pop
ans * 10 + pop > MAX_VALUE这个溢出的条件来看

  • 当出现ans > MAX_VALUE/10且还有pop需要添加时,则一定会溢出
  • 当出现ans == MAX_VALUE/10pop>7时,则一定会溢出,因为7是2^31^-1的个位数
    ans * 10 + pop < MIN_VALUE这个溢出条件来看
  • 当出现ans < MIN_VALUE/10 且还有pop需要添加的时候,则一定会溢出
  • 当出现ans == MIN_VALUE/10pop <-8时,则一定会溢出,8是-2^31^的个位数

分析来源:https://leetcode-cn.com/problems/reverse-integer/solution/hua-jie-suan-fa-7-zheng-shu-fan-zhuan-by-guanpengc/

class Solution {
    public int reverse(int x) {
        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;
    }
}
  • 补充:将上面的代码尝试使用python3进行编写之后,发现出现了问题:

    • 1、python和C语言、java等主流的编程语言的求余的结果是有区别的,特别是负数的时候
    • 2、在数学定义中,他们的求余公式是一样的,都是r=a-n*[a/n],其中r是余数,a是被除数,n是除数。
    • 3、唯一的不同:就是商向0或者负无穷方向取整的选择,C和java等语言规定是向0取整的,而Python则规定向负无穷取整,选择底层机制不同:例如:
      向零取值的涵义是:9/7=1.29 ----向0取整–>1; -9/7=-1.29----向0取值------>-1
      向负无穷取值的涵义是:9/7=1.29----向0取值–>1;-9/7=-1.29----向0取值------>-2
      • 例1:print(-123%10) # 输出 7
      • 例2:print(-123%-10) # 输出 -3
      • 上面的例1输出的7真的是有点摸不着头脑,原因是在“a//n”这一步,当a是负数的时候,我们上面说了,会向下取整,也就是说向负无穷方向取整。这也就得到:
        -123%10 = -123 - 10 * (-123 // 10) = -123 - 10 * (-13) = 7
      • 如果将除数换成负数,如:print(123%-10),会得到结果-7
  • 下面是将上面的java代码改编程python3的代码,但是正是由于上面的余数问题,改编的并不顺利,使用python的切片等其他的方法会更好

  • 下面的例子是有点问题的:仅仅作为记录:例如-10就不通过:

class Solution:
    def reverse(self, x: int) -> int:
        ans = 0
        while x != 0:
            if x > 0:
                pop = x % 10
            else:
                # 取余应该是负数的
                pop = x % (-10)
            max_value = 2**31-1
            min_value = -2**31
            if (ans > max_value//10 or (ans == max_value//10 and pop > 7)):
                return 0
            if (ans < min_value//10 or (ans == min_value//10 and pop < -8)):
                return 0
            ans = ans * 10 + pop
            if x > 0:
            # 不能使用 x /= 10,因为我想得到的是整数而不是小数
                x = x//10
            else:
                # 在求取商值的时候,需要向0取整
                x = x//10 + 1
        return ans
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值