リンク:https://zhuanlan.zhihu.com/p/23967316
出典:
著者がほぼ著作権を所有していることを知ってい ます。商用の再版については、著者に連絡して許可を得てください。非商用の再版については、出典を示してください。
リンク
https:// leetcode.com/problems/z igzag-conversion /
トピック
例1:x = 123、戻り値321
例2:x = -123、戻り値-321
ルールはとてもシンプルに見えますが、いくつかの特別なシナリオを考えましたか?
質問をした人もとても気を配っていたので、最初にプロンプトを折りたたんで、もっと考えるように促しました
はい、特別なシーンについて考えてから見下ろしてください
さて、あなたが本当にそれについて考えたならば、ここにタイトルのためのヒントがあります:
- 最後の数ビットが0の場合、出力はどのようになりますか?10100のように?
- 反転した整数がオーバーフローする可能性があることをご存知ですか?32ビット整数の場合、最大値は2147483648であり、反転後に1000000003がオーバーフローします。この場合、出力は0である必要があります。
関数定義
leetcodeで指定された関数定義は次のようになります。
class Solution {
public:
int reverse(int x) {
}
};
問題解決のアイデア
オーバーフローが考慮されていない場合、このトピックのアイデアは簡単に考えることができます:
- 各桁の数値を取得するには、整数の除算と剰余演算を使用できます。ループを作成して、最初は10で除算し、2回目は100で除算する必要があります。。。
- 結果として得られる一連の数値について、最初の桁に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;
}
};
確認するためにコードを送信した後、この状況に対処していないため、オーバーフローエラーが報告されます
入力を非常に大きな数に変更した後、実行時に例外がないことがわかりました。または、境界値を使用して正直に判断します
この実現のための良い解決策を考えていなかったので、ディスカッションエリアを調べました。
https://でdiscuss.leetcode.com/to PIC / 287 /どのように-DO-WE-ハンドルオーバーフローケース/ 12
https://でdiscuss.leetcode.com/to PIC / 6005 /最短コード可能型C
変更されたコードの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つのループをマージできることがわかります。これは、すべての人に任されています。
さらに、整数を文字列に変換することもできます〜