题目:
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
代码:
class Solution { public: int divide(int dividend, int divisor) { if (divisor==0) return dividend>=0 ? INT_MAX : INT_MIN; if (divisor==-1 && dividend==INT_MIN) return INT_MAX; // record negative or positive int sign = 1; sign = dividend<0 ? -sign : sign; sign = divisor<0 ? -sign : sign; // transfer to non negative long long type & get rid of overflow unsigned long long _dividend = abs((long long)dividend); unsigned long long _divisor = abs((long long)divisor); if ( _dividend < _divisor ) return 0; // using bit manipulation to simulate binary multiply unsigned long step = 1; while ( _dividend > _divisor ) { _divisor = _divisor << 1; step = step << 1; } // cout << "step:" << step << endl; // cout << "_divisor:" << _divisor << endl; unsigned long res = 0; while ( _dividend >= abs((long long)divisor) ) { while ( _dividend >= _divisor) { _dividend -= _divisor; res = res + step; } _divisor = _divisor >> 1; step = step >> 1; } return sign==1 ? res : -res; } };
tips:
这道题非常好,即考查了bit manipulation又考查了类型转换的细节。
做题的过程中,学习了下面这个blog的优秀思路(http://yucoding.blogspot.sg/2013/01/leetcode-question-28-divide-two-integers.html)
1. 不让用乘法、除法、幂运算等。但还是要做除法,这个时候可以用bit manipulation。本质就是用二进制运算代替十进制运算。
比如 155/3 ,如果不让你用除法,只允许用乘法或加法,该怎么做呢?
做法1(加法):
3+3+...+3+3==153,result=51
这种解法最直观,但也最耗时,时间复杂度为O(n)
做法2(乘法+加法):
1)3*100=300>155 , 得知result<100,10个3*10大于被除数
2)3*10=30<155, 得知result>10 1个3*10小于被除数
155-30-30-30-30-30==5<30, result = result +50
3) 3*1=3<5,得知result大于一个3*1小于10个3*1
5-3=2<3,result = result +1 = 51
最终得到的结果是 155 = 3*5*10^1 + 3*1*10^0 + 2。
解释如下,如果用10的幂构成的多项式(多项式每个项目前面有固定的系数就是被除数);
并在每一项前面配上一个变化系数(加颜色),155就被表示上述的形式
显然做法2的时间复杂度log(n)更低,按照题意的要求,乘以10这种做法肯定是不行了,所以把10换成2,改用移位运算。