29 Divide Two Integers
链接:https://leetcode.com/problems/divide-two-integers/
问题描述:
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
Hide Tags Math Binary Search
设计一个自己的除法算法。很容易想到用减法的思路来做除法。我的想法是除数不断扩大10倍,直到下一次扩大会大于被除数。记录每一个中间扩大的数字,然后用被除数减去记录下来的数字来做除法。这里需要十分小心的是溢出问题,因为要转化到做减法的过程,首先需要做的是将除数和被除数做绝对值。而int能表示
-2147483648却不能表示2147483648,因此需要转换为long long int。
class Solution {
public:
int divide(int dividend, int divisor) {
if(divisor==0) return INT_MAX;
bool flag=true;
if((dividend<0&&divisor>0)||(dividend>0&&divisor<0)) flag=false;
long long int mdividend=abs((long long int)dividend);
long long int mdivisor=abs((long long int)divisor);
long long int result=0;
int i=0;
vector<long long int> vi;
for(;mdivisor<=mdividend;i++)
{
vi.push_back(mdivisor);
mdivisor*=10;
}
for(int i=vi.size()-1;-1<i;i--)
{
while(mdividend>=vi[i])
{
mdividend-=vi[i];
result+=pow(10,i);
}
}
if(!flag)
result=-result;
if(result>INT_MAX||result<INT_MIN)
return INT_MAX;
return result;
}
};
这个解法可能违背题目中不能用乘法的要求。那么可以做适当转换。原来我用扩大10倍来做减数,那么我也可以通过扩大2倍的方式来,这样就能引入位移操作,避免了乘法。不管是扩大10倍还是扩大2倍都无所谓,因为结果都可以表示成以10的幂为底的一组基的线性组合或者以2的幂为底的一组基的线性组合。
class Solution {
public:
int divide(int dividend, int divisor) {
if(divisor==0) return INT_MAX;
bool flag=true;
if((dividend<0&&divisor>0)||(dividend>0&&divisor<0)) flag=false;
long long int mdividend=abs((long long int)dividend);
long long int mdivisor=abs((long long int)divisor);
long long int result=0;
int i=0;
vector<long long int> vi;
for(;mdivisor<=mdividend;i++)
{
vi.push_back(mdivisor);
mdivisor<<=1;
}
for(int i=vi.size()-1;-1<i;i--)
{
while(mdividend>=vi[i])
{
mdividend-=vi[i];
result|=((long long int)1<<i);
}
}
if(!flag)
result=-result;
if(result>INT_MAX||result<INT_MIN)
return INT_MAX;
return result;
}
};