实现除法操作
前文
一、算法題介紹
對除數(shù)和被除數(shù)實現(xiàn)除法運算,其中不使用乘法、除法和求余操作,返回對應(yīng)的商。如,
Input: dividend = 10, divisor = 3
Output: 3
解法1:暴力解法
class Solution {public int divide(int dividend, int divisor){//定義除法,被除數(shù)是最小值,除以-1時,是最大值if(dividend == Integer.MIN_VALUE && divisor == -1)return Integer.MAX_VALUE;//^運算符,只有不同時,才為true ; sign定義商是否為負數(shù) int sign = (dividend < 0) ^ (divisor < 0) ? -1 : 1;int result = 0;//取除數(shù)和被除數(shù)的正數(shù)形式long x = Math.abs((long)dividend);long y = Math.abs((long)divisor);//統(tǒng)計被除數(shù)共減去多少個除數(shù),即為商while(x >= y){x -= y;result++;}return sign > 0 ? result : -result;} } 復(fù)制代碼- 時間復(fù)雜度:O(x),x是被除數(shù)。
- 空間復(fù)雜度:O(1)。
解法2:除數(shù)左移位累加
class Solution {public int divide(int dividend, int divisor){if(dividend == Integer.MIN_VALUE && divisor == -1)return Integer.MAX_VALUE;int sign = (dividend < 0) ^ (divisor < 0) ? -1 : 1;int result = 0;long x = Math.abs((long)dividend);long y = Math.abs((long)divisor);while(x >= y){int shift = 1;//將y持續(xù)向左移位,相當(dāng)于y*2^(shift);//當(dāng)y*2^(shift)< x <y*2^(shift+1)時,循環(huán)結(jié)束while(x >= (y << shift)){shift++;}x -= y << (shift - 1);//相當(dāng)于x = y*2^(shift)+y*2^(shift-n)+.....+y*2^(0) + m;m是余數(shù)result += 1 << (shift - 1);}return sign > 0 ? result : -result;} } 復(fù)制代碼- 時間復(fù)雜度:O(n2),n是x/y的商的位數(shù)。
- 空間復(fù)雜度:O(1)。
解法3:除數(shù)左移位遞減
class Solution {public int divide(int dividend, int divisor){if(dividend == Integer.MIN_VALUE && divisor == -1)return Integer.MAX_VALUE;int sign = (dividend < 0) ^ (divisor < 0) ? -1 : 1;int result = 0;int power = 32;//long是8字節(jié),64位;int是4字節(jié),32位long x = Math.abs((long)dividend);long y = Math.abs((long)divisor);while(x >= y){//將y*2^32增加到最大,然后逐步減小,靠近x//y*2^power<x時結(jié)束while((y << power) > x){//每次只需要執(zhí)行有限步就能找到power,不像前面中的方法,是執(zhí)行O(n)步才能找到power--;}x -= y << power;result += 1 << power;}return sign > 0 ? result : -result;} } 復(fù)制代碼1.在每次循環(huán)中找到最大的k的最好的方式就是認識到k其實是在不斷縮小的。因此,我們不需要在每次子循環(huán)的時候都檢驗一下21,22,23......是否小于或者等于x,我們可以在找到最大的k后,直接在后面的每次循環(huán)中檢驗x和2k-1,2k-2,2k-3....的關(guān)系。
2. 我們可以繼續(xù)之前的例子。商為(100)2后,我們繼續(xù)計算(11)2。因為y*2k<=x的最大k是0,所以我們把20=(1)2加到商里,因此商就變成了(101)2。然后我們繼續(xù)算法,因此(1)2<y,所以算法結(jié)束。最后,我們可以得到,x= (1011)2,y=(10)2相除,商為(101)2,余數(shù)為(1)2。
- 時間復(fù)雜度:O(n),n是x/y的商的位數(shù)。
- 空間復(fù)雜度:O(1)
總結(jié)
- 上一篇: ansible配置详解及基本示例
- 下一篇: -1对256取模