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++),其它的各種都是一些特例。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM