Divide Two Integers

Divide two integers without using multiplication, division and mod operator.

 

方法一:暴力破解,不断用被除数减去除数,直至出现负数停止,铁定超时。

 

方法二:对方法一的改进,每次寻找 满足2k-1 * 除数 <= 被除数 < 2k * 除数第一个k,那么被除数直接减去 2k-1 个除数,同时积累商值,更新被除数

需要注意溢出的问题。

 

 1 class Solution {
 2 public:
 3     int divide(int dividend, int divisor) {
 4         bool minus = false;
 5         if( (dividend>0 && divisor<0) || (dividend<0 && divisor>0) ) minus = true;  //判断正负
 6         long long divd = abs((long long)dividend);  //防止溢出
 7         long long divs = abs((long long)divisor);
 8         long long ans = 0;
 9         while( divd >= divs ) { //如果被除数依然大于除数,表明可以继续减
10             long long tmp = divs;
11             int i=0;
12             while( tmp <= divd ) {  //寻找第一个满足2k-1 * 除数 <= 被除数 < 2k * 除数的k
13                 tmp <<= 1;
14                 ++i;
15             }
16             ans += 1<<(i-1);    //积累商值
17             divd -= tmp>>1;     //被除数更新
18         }
19         return minus ? -ans : ans;
20     }
21 };

 

 

方法三:二分搜索商值,可以确定商值在[0,被除数]之间,因此可以在这区间不断进行二分搜索,由于不能使用乘法,除法,取模操作,那么计算 商*除数的 运算修改为加、减、移位操作,即multic * num = multic 为偶数,multic/2 * num * 2 或 multic 为奇数,multic/2 * num * 2 + num,那么时间复杂度就为O(lognlogn)

 1 class Solution {
 2 public:
 3     int divide(int dividend, int divisor) {
 4         bool minus = false;
 5         if( (dividend>0 && divisor<0) || (dividend<0 && divisor>0) ) minus = true;
 6         long long divd = abs((long long)dividend);
 7         long long divs = abs((long long)divisor);
 8         long long ans = 0;
 9         long long left = 0, right = divd;   //确定搜索区间
10         while( left <= right ) {
11             long long mid = left + ( (right-left) >> 1 );   //取中
12             long long tmp = multiple(mid, divs);    //计算mid * 除数
13             if( tmp == divd ) {     //如果乘后的值等于被除数
14                 ans = mid;
15                 break;
16             }
17             if( tmp < divd ) {  //如果乘后值小于,那么应该增大商
18                 ans = mid;
19                 left = mid+1;
20             }
21             else right = mid-1; //否则减少商
22         }
23         return minus ? -ans : ans;
24     }
25     
26     long long multiple(long long multic, long long num) {   //分治法求a*b
27         if( multic == 0 ) return 0;
28         long long ans = multiple(multic>>1, num) << 1;  //先求a/2 * b,在将值乘2
29         if( multic & 1 ) ans += num;    //如果a为奇数
30         return ans;
31     }
32 };

 

posted on 2014-10-01 23:24  bug睡的略爽  阅读(130)  评论(0编辑  收藏  举报

导航