1. 程式人生 > >Leetcode刷題日記

Leetcode刷題日記

第二題 Reverse Integer

從今天開始記錄,學習總有個規律和過程,慢慢來,人生大部分遇到的問題都可以從前人的經驗中找到答案,多看看書

題目描述:

Reverse digits of an integer.

Example1: x = 123, return 321
Example2: x = -123, return -321

The input is assumed to be a 32-bit signed integer. Your function should return 0 when the reversed integer overflows

提示裡面說是
1、首先要排除數字末尾的零干擾 如120 翻轉之後就變為21
2、其次是溢位問題,32位整數會有表達限制,資料範圍

拿到這道題首先的思路肯定是翻轉數字的演算法,樸素的方法,取出各個數位然後儲存到一個數組中然後倒序輸出陣列即可

while(x!=0){
        temp[size]=x%10;
        x/=10;
        size++;
    }

取出的時候也用相同的辦法

   for(int i=0;i<size;i++)
    {
            result *= 10;
            result += temp[i];
    }

這種演算法最終結果是按照陣列對應元素的下標進行加權最終得到的結果,所以第一個問題可以解決,也不必擔心正負號問題。

關鍵的問題在於判斷溢位,首先要判斷輸入資料的範圍,輸入資料是標準的32位Int型整數,範圍是-2147483648~2147483647,輸出也是int型。由於輸入的限制,找不到一個數翻轉之後為2147483647,所以不必擔心資料能夠到表達範圍的極限。

最開始我過分擔心這個問題,還引入了判斷輸入數的正負來決定最終比較用的是Integer.MAX_VALUE還是Integer.MIN_VALUE,最終發現這是沒有必要的,一切變化都是建立在輸入自變數的基礎上的,沒有必要處理離開自變數範圍的資料。

判斷溢位,本身我的想法是溢位時資料有效位數已經到達了10位,在程式中判斷一旦數字位數到達了十位,便把相應的陣列和代表數字最大值的陣列比較,按位相互比較,判斷該數字和整數範圍之間的關係。此時還有一個問題,由於輸入陣列中有正數有負數,所以判斷時的正負還要判斷。

if(size>=10)
    {
        int compare[10],num=0;
        unsigned int a =0;
        int MAX = (~a)/2;
        if(flag)
            MAX = -MAX;
        while(MAX!=0)
        {
            compare[num]=MAX%10;
            MAX/= 10;
            num++;
        }
        if(flag)
        {
            for(int i=0;i<10;i++)
            {
            if(temp[i]<compare[9-i])
                return 0;
            if(temp[i]>compare[9-i])
                break;
            if(temp[i]==compare[9-i])
                continue;
            }
        }
        for(int i=0;i<10;i++)
        {
            if(temp[i]>compare[9-i])
                return 0;
            if(temp[i]<compare[9-i])
                break;
            if(temp[i]==compare[9-i])
                continue;
        }
    }

按照這個思路寫是沒什麼大問題,演算法的複雜度由於輸入資料的範圍限制也不會很高,但是始終顯得不是很優雅,於是參考別人的方法。

整個過程中可以優化的地方有兩個
* 一個是對溢位的判斷顯得太過繁瑣,可以直接用數字的運算進行判斷而無需擔心運算的過程中資料溢位,這就牽涉到怎麼寫這個運算的問題了。
* 二是沒有必要使用使用臨時陣列來進行中間的儲存,使用得當,所有的過程可以在一次迴圈中解決,這樣既提升了效率又顯得非常優雅,要學的地方還有很多。

class Solution{
public:
    int reverse(int x){
        unsigned int a = 0;
        int MAX_VALUE = (~a)/2;
        int MIN_VALUE = -(MAX_VALUE+1);
        //temp表示每次取出來的數位值 
        int result =0,temp = 0;
        bool flag =false;
        //取絕對值 標記正負 
        if(x<0){
            flag = true;
            x = -x;
        } 
        while(x!=0){
            temp = x%10; 
            if(result!=0){
                if(((MAX_VALUE-temp)/result <10)||((MIN_VALUE+temp)/result>-10))
                    return 0;
            }
            result = result*10+temp;
            x/=10;
        }
        if(flag)
            result = -result;

        return result; 
    }
    };