zoukankan      html  css  js  c++  java
  • LeetCode(7):颠倒整数

    Easy!

    题目描述:给定一个范围为 32 位 int 的整数,将其颠倒。

    例1:

    输入:132

    输出:321

    例2:

    输入:-123

    输出:-321

    例3:

    输入:120

    输出:21

    注意:假设我们的环境只能处理 32 位 int 范围内的整数。根据这个假设,如果颠倒后的结果超过这个范围,则返回 0。

    解题思路:

    翻转数字问题需要注意的就是溢出问题。由于之前的OJ没有对溢出进行测试,所以网上很多人的解法没有处理溢出问题也能通过OJ。现在OJ更新了溢出测试,所以还是要考虑到。为什么会存在溢出问题呢,我们知道int型的数值范围是 -2147483648~2147483647, 那么如果我们要翻转 1000000009 这个在范围内的数得到 9000000001,而翻转后的数就超过了范围。
    我最开始的想法是,用long long 型数据,其数值范围为 -9223372036854775808~9223372036854775807, 远大于int型这样就不会出现溢出问题。代码如下:

    C++参考答案一:

     1 /**
     2  * Correct but can refactor the code.
     3  */
     4 class Solution {
     5 public:
     6     int reverse(int x) {
     7         long long res = 0;
     8         bool isPositive = true;
     9         if (x < 0) {
    10             isPositive = false;
    11             x *= -1;
    12         }
    13         while (x > 0) {
    14             res = res * 10 + x % 10;
    15             x /= 10;
    16         }
    17         if (res > INT_MAX) return 0;
    18         if (isPositive) return res;
    19         else return -res;
    20     }
    21 };

    提交通过后,OJ给出了官方解答,一看比自己的写的更精简一些,它没有特意处理正负号,仔细一想,果然正负号不影响计算,而且没有用long long型数据,感觉写的更好一些,那么就贴出来吧:

    C++参考答案二:

     1 class Solution {
     2 public:
     3     int reverse(int x) {
     4         int res = 0;
     5         while (x != 0) {
     6             if (abs(res) > INT_MAX / 10) return 0;
     7             res = res * 10 + x % 10;
     8             x /= 10;
     9         }
    10         return res;
    11     }
    12 };

    在贴出答案的同时,OJ还提了一个问题 To check for overflow/underflow, we could check if ret > 214748364 or ret < –214748364 before multiplying by 10. On the other hand, we do not need to check if ret == 214748364, why? (214748364 即为 INT_MAX / 10)

    为什么不用check是否等于214748364呢,因为输入的x也是一个整型数,所以x的范围也应该在 -2147483648~2147483647 之间,那么x的第一位只能是1或者2,翻转之后res的最后一位只能是1或2,所以res只能是 2147483641 或 2147483642 都在int的范围内。但是它们对应的x为 1463847412 和 2463847412,后者超出了数值范围。所以当过程中res等于 214748364 时, 输入的x只能为 1463847412, 翻转后的结果为 2147483641,都在正确的范围内,所以不用check。

    我们也可以用long long型变量保存计算结果,最后返回的时候判断是否在int返回内,参见代码如下:

    C++参考答案三:

     1 class Solution {
     2 public:
     3     int reverse(int x) {
     4         long long res = 0;
     5         while (x != 0) {
     6             res = 10 * res + x % 10;
     7             x /= 10;
     8         }
     9         return (res > INT_MAX || res < INT_MIN) ? 0 : res;
    10     }
    11 };

    下面这种方法是上面解法二的变形,其实也不难理解,因为都是用int型的,如果超出了范围,其除以10的结果就不会跟之前的结果一致,通过这点也可以进行区分,参见代码如下:

    C++参考答案四:

     1 class Solution {
     2 public:
     3     int reverse(int x) {
     4         int res = 0;
     5         while (x != 0) {
     6             int t = res * 10 + x % 10;
     7             if (t / 10 != res) return 0;
     8             res = t;
     9             x /= 10;
    10         }
    11         return res;
    12     }
    13 };

    基础知识回顾:

    一、

    INT_MIN在标准头文件limits.h中定义。

    1 #define INT_MAX 2147483647
    2 #define INT_MIN (-INT_MAX - 1)

    在C/C++语言中,不能够直接使用-2147483648来代替最小负数,因为这不是一个数字,而是一个表达式。表达式的意思是对整数21473648取负,但是2147483648已经溢出了int的上限,所以定义为(-INT_MAX -1)。

    C中int类型是32位的,范围是-2147483648到2147483647 。 
    (1)最轻微的上溢是INT_MAX + 1 :结果是 INT_MIN; 
    (2)最严重的上溢是INT_MAX + INT_MAX :结果是-2; 
    (3)最轻微的下溢是INT_MIN - 1:结果是是INT_MAX; 
    (4)最严重的下溢是INT_MIN + INT_MIN:结果是0 。

    二、

    求数字的绝对值,vc++提供的库函数的支持,当必须包含:#include <math.h>

    其中又分好几种类型:abs、_abs64、fabs、fabsf、labs、_cabs。详细说明如下:
    //Calculate the absolute value.
    int abs( 
       int n 
    );
    long abs( 
       long n 
    );   // C++ only
    double abs( 
       double n 
    );   // C++ only
    long double abs(
       long double n
    );   // C++ only
    float abs(
       float n 
    );   // C++ only
    __int64 _abs64( 
       __int64 n 
    );
    //Calculates the absolute value of the floating-point argument.
    double fabs( 
       double x 
    );
    float fabs(
       float x 
    ); // C++ only
    long double fabs(
       long double x
    ); // C++ only
    float fabsf( 
       float x 
    );
    //Calculates the absolute value of a long integer.
    long labs(
          long n 
    );
    //Calculates the absolute value of a complex number.
    double _cabs( 
       struct _complex z 
    );

    以上函数的原型说明来自MSDN2008,可以看出,abs()函数有很多重载形式。一般用abs()就可以满足要求(c++),其它的各种都是一些特例。

  • 相关阅读:
    CF1580B Mathematics Curriculum
    [机房测试]变异大老鼠
    http_缓存
    UDP_概述
    记录: webAssembly 延申
    Event
    NetWork_timeLine
    基于Typora的Latex代码书写并移植到word中
    ZooKeeper学习总结
    HBase学习总结
  • 原文地址:https://www.cnblogs.com/ariel-dreamland/p/8706403.html
Copyright © 2011-2022 走看看