LeetCodeブラッシングノート07逆整数

著者:Ma Zhifeng
リンク:https://zhuanlan.zhihu.com/p/23967316
出典:
著者がほぼ著作権を所有していることを知ってい ます。商用の再版については、著者に連絡して許可を得てください。非商用の再版については、出典を示してください。

リンク

leetcode.com/problems/z

トピック

例1:x = 123、戻り値321
例2:x = -123、戻り値-321

ルールはとてもシンプルに見えますが、いくつかの特別なシナリオを考えましたか?

質問をした人もとても気を配っていたので、最初にプロンプ​​トを折りたたんで、もっと考えるように促しました

はい、特別なシーンについて考えてから見下ろしてください

さて、あなたが本当にそれについて考えたならば、ここにタイトルのためのヒントがあります:

  1. 最後の数ビットが0の場合、出力はどのようになりますか?10100のように?
  2. 反転した整数がオーバーフローする可能性があることをご存知ですか?32ビット整数の場合、最大値は2147483648であり、反転後に1000000003がオーバーフローします。この場合、出力は0である必要があります。

関数定義

leetcodeで指定された関数定義は次のようになります。

class Solution {  
public:  
    int reverse(int x) {  

    }  
};

問題解決のアイデア

オーバーフローが考慮されていない場合、このトピックのアイデアは簡単に考えることができます:

  1. 各桁の数値を取得するには、整数の除算と剰余演算を使用できます。ループを作成して、最初は10で除算し、2回目は100で除算する必要があります。
  2. 結果として得られる一連の数値について、最初の桁に1を掛け、2番目の桁に10を掛け、3番目の桁に100を掛けます。、そして合計して反転数を取得します

オーバーフローの場合、単純で失礼な方法は、try ... catch ...が適切かどうかを確認することです。

  • 必要に応じて、キャッチで直接0を返します。
  • 適切でない場合は、整数型の最大値を見つける必要があります

擬似コード

x = 123;
xは10の余りで3を取得し、xを10で除算して12を取得し、
12は10で除算して1を取得します
。1は10の余りを取得します。1を取得し、xを10で割って0を取得します。

1 * 1 + 2 * 10 + 3 * 100 = 321

コード

class Solution {  
public:  
    int reverse(int x) {  
        if (x < 10 && x > -10)  
        {  
            return x;  
        }  

        vector<int> vecDigits;  
        int iTemp = x;  
        do  
        {  
            vecDigits.push_back(iTemp % 10);  
            iTemp = iTemp / 10;  
        } while (iTemp != 0);  

        auto iSize = vecDigits.size();  
        int iFactor = 1;  
        int iResult = 0;  
        for (auto i = iSize - 1; i >= 0; --i)  
        {  
            iResult += iFactor * vecDigits[i];  
            iFactor *= 10;  
        }  

        return iResult;  
    }  
};

コードを記述したら、x = 123に置き換えて確認します

まあ、すべてがうまく見えます。

しかし、送信すると「ランタイムエラー」が表示されます!なぜですか?

わからない場合は、戻って「c ++入門書」の34ページをご覧ください。

はい、無限ループがあります。悲しいことに。読んでいると、そんな間違いはしないと思いました。

class Solution {  
public:   
    int reverse(int x) {  
        if (x < 10 && x > -10)  
        {  
            return x;  
        }  

        vector<int> vecDigits;  
        int iTemp = x;  
        do  
        {  
            vecDigits.push_back(iTemp % 10);  
            iTemp = iTemp / 10;  
        } while (iTemp != 0);  

        auto i = vecDigits.size();  
        int iFactor = 1;  
        int iResult = 0;  

        while (i > 0)  
        {  
            --i;  
            iResult += iFactor * vecDigits[i];  
            iFactor *= 10;  
        }  

        return iResult;  
    }  
};

確認するためにコードを送信した後、この状況に対処していないため、オーバーフローエラーが報告されます

入力を非常に大きな数に変更した後、実行時に例外がないことがわかりました。または、境界値を使用して正直に判断します

この実現のための良い解決策を考えていなかったので、ディスカッションエリアを調べました。

discuss.leetcode.com/to

discuss.leetcode.com/to

変更されたコードの1つを参照します

class Solution {  
public:  
    int reverse(int x) {  
        if (x < 10 && x > -10)  
        {  
            return x;  
        }  

        vector<int> vecDigits;  
        int iTemp = x;  
        do  
        {  
            vecDigits.push_back(iTemp % 10);  
            iTemp = iTemp / 10;  
        } while (iTemp != 0);  

        auto i = vecDigits.size();  
        long long iFactor = 1;  
        long long iResult = 0;  

        while (i > 0)  
        {  
            --i;  
            iResult += iFactor * vecDigits[i];  
            iFactor *= 10;  
        }  

        if (iResult > INT_MAX || iResult < INT_MIN)  
        {  
            return 0;  
        }  

        return iResult;  
    }  
};

さて、ようやく受け入れられました。

しかし、ディスカッションエリアを見ると、2つのループをマージできることがわかります。これは、すべての人に任されています。

さらに、整数を文字列に変換することもできます〜

おすすめ

転載: blog.csdn.net/qq_26751117/article/details/53442415