好像通过率比较低,因为在边界上面处理比较麻烦。特别是这个数据,一个需要去注意的数据
题目的意思是:就是 不用乘除,取模这三种方式去计算出商
,注意这个商保存的是的整数部分。听了讲解之后大概能明白意思。其实从本质上面来说还是使用了乘除,因为位运算替代了乘法的操作。
假设我们的出书和被除数为x的y,我们计算出的结果为k。那么数学化的形式语言就为:x/y=k。但是次数并不能失去使用除法。我们间接去进行转化一下。
=>x-k*y=0。
但是此时还是使用到了乘法啊,这一再去进行转化,将答案k转化成二进制的形式,因为通过二进制的形式,我么可以通过位运算间接的得到答案。那么我们转化成的形式如下:
x-(2^k1 + 2^k2+ 2^k3+......++ 2^kn)=0
那么此时我们的任务只要求出k1,k2,k3.....kn就可以了。然后通过位运算计算出总和就行了。
那么如何求出: 答案的二进制形式的各个指数大小呢?用倍增的方法
,这里不要和LCA(最小公共祖先混淆了)。就是简单地去翻倍而已。其实还是和二进制进行一点点的关联。
从被除数开始到除数,然后存储到质数位上面。
比如,我们的除数和被除数分别是:17 4
那么我们计算出指数位分别为 4 8 16。索引的位置分别为1,2 ,3。现在在去处理位,通过递减计算
代码如下:
class Solution {
public:
int divide(int x, int y) {
// //不使用乘除取模
typedef long long LL;
vector<LL> exp;//计算出每一个数的指数部分
bool f=false;
//先判断出负数的情况
if(x<0&&y>0||x>0&&y<0) f=true;
//然后再去转化成整数的情况去进行计算
LL a=abs((LL)x),b=abs((LL)y);
for(LL i=b;i<=a;i=i+i) exp.push_back(i);
//现在处理指数的部分
LL res=0;
for(int i=exp.size()-1;i>=0;i--){
//先处理最高位的数字
if(a>=exp[i]){
a-=exp[i];
res+=1ll<<i;//res*2^i;
}
}
if(f) res=-res;
if(res>INT_MAX||res<INT_MIN) res=INT_MAX;
return res;
}
};