【LeetCode】29.2つのカウントダウン(JAVA)

5981 ワード

元の住所:https://leetcode-cn.com/problems/divide-two-integers/
題目の説明:与えられた二つの整数は、除数dividendと除数divisorである。乗算、除算、およびmod演算子を使用しないことが必要です。
除数されたdividendで除数されたdivisorで得られた商を返します。
例1:入力:dividend=10、divisor=3出力:3
例2:入力:dividend=7、divisor=-3出力:-2
説明:
  • の除算および除算は、ともに32ビットの符号付き整数である。
  • 除数は0ではない。
  • 私たちの環境は32ビットの符号付き整数しか記憶できないと仮定しています。その数値範囲は[−2 31,2 31−1][\sf−2^{31},2^{31}−1[−231,231−1]です。本題では、除算結果がオーバーフローすると、2 31−1>sf 2^{31}−1 231−1−1に戻ります。
  • この問題を作るのは大変です。もともとは数の記憶と処理がよく分かりませんから。問題解も長い間見てやっと分かりました。
  • は、まず、被除数を倍増させ、もし除数が倍後の数よりも大きいなら、i\sf i iの倍を返したら、2 i\sf 2^i 2 iの除数があります。(ここで注意すべき点があります。Integer.MINUVALEを超えるまでは倍にしてはいけませんので、条件制限を加えます。)
  • は、ある程度まで倍増した後の除算数が倍を超えた数より小さい場合、この数を差し引いて再計算します。栗を挙げて、29を割って、6を割って18まで倍にすると、29-18=11はさらに6倍になるので、残りの数が除数より少なくなるまで繰り返します。
  • 注意:符号数がある格納の第一位は符号であるため、負の数は正の数よりも一つ多いので、除数はInteger.MIN_である。VALE、除数は-1の時に境界を越えて、単独で討論します。また、異号の場合は同じ番号に変換して計算します。正数になるとやはり境界を越えるので、マイナス記号に変えて計算します。
    コード:
    class Solution {
        public int divide(int dividend, int divisor) {
            if(dividend == Integer.MIN_VALUE && divisor == -1)
                return Integer.MAX_VALUE;
            boolean flag = (dividend ^ divisor) < 0;
    
            int tmp_divisor, count = 1, res = 0;
            dividend = -Math.abs(dividend);
            divisor = -Math.abs(divisor);
            tmp_divisor = divisor;
            while(dividend <= divisor)
            {
                tmp_divisor = divisor;
                count = 1;
                while(dividend <= (tmp_divisor << 1))
                {
                    if(tmp_divisor <= (Integer.MIN_VALUE >> 1)) break;
                    tmp_divisor = tmp_divisor << 1;
                    count = count << 1;
                }
                res += count;
                dividend -= tmp_divisor;
            }
    
            if(flag) return -res;
            else return res;
        }
    }