【Leetcode】【Divide Two Integers】【两数相除】【C++】
- 题目:
给定两个整数,被除数
dividend
和除数divisor
。将两数相除,要求不使用乘法、除法和 mod 运算符。返回被除数
dividend
除以除数divisor
得到的商。 - 说明:
- 被除数和除数均为 32 位有符号整数。
- 除数不为 0。
- 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。本题中,如果除法结果溢出,则返回 231 − 1。
- 思路:
- 本来首先想到的加减计数,例如dividend=15,divisor=3 用15一直减3,看可以减多少次(直到剩余的差小于3),但这样会超时;网上搜索了该题目,阅读了思路和代码好久,才弄懂。现将算法较详细得叙述如下:
- a) 设divid,divis为dividend,divisor对应的绝对值(溢出情况会另外处理,此处暂不考虑),以divid=73(二进制为:0100 1001),divis=5(二进制为:0101) //注:前面多余的0不再表示; 设一个计数器cnt, 每次cnt求得的结果为(设divis可以左移的最大位数为n,则cnt=2n,换句话说,divis左移log2[cnt]位后,刚好满足divis>divid)
- b) 初始 divid= 0100 1001 divis=0101 显然,当divis左移4位时,得到 temp=0101 0000,刚好满足temp>divid, 此时cnt=1 0000; 此时temp=(divis*24),由于temp刚好大于divid, 故 divis*23一定小于divid, 即divis*23<divid, 由此可知 divid里面至少有23个divis,故res累加8;
- 说明:此步骤的关键是求得对应的cnt 用一个while循环即可实现
- c) 更新 divid=divid-(temp>>1),即 temp=temp- divis*23 ; 再次循环b)即可 直到divis>divid;
- 本来首先想到的加减计数,例如dividend=15,divisor=3 用15一直减3,看可以减多少次(直到剩余的差小于3),但这样会超时;网上搜索了该题目,阅读了思路和代码好久,才弄懂。现将算法较详细得叙述如下:
- 代码:
class Solution { public: long long abs(int n) { long long n1=n; if(n1<0) n1=-1*n1; return n1; } int divide(int dividend, int divisor) { long long res=0; int int_min=1<<31; int int_max=(int_min>>31) ^ int_min; long long divid = dividend; long long divis = divisor; bool resNeg = false; if((divid>0 && divis<0) || (divid<0 && divis>0)) resNeg = true; divid = abs(divid); divis = abs(divis); if(divis==1 && (divid-1)==int_max && !resNeg) { //cout<<"uicio"; res=int_max; return int_max; } long long cnt=0; cout<<divis<<" "<<divid<<endl; while(divis<=divid) { cnt=1; long long temp=divis; while(temp<=divid) { temp = temp<<1; cnt = cnt<<1; } cout<<(cnt>>1)<<endl; res += (cnt>>1); divid -= (temp>>1); } if(resNeg) return -1*res; return res; } };
说明:第一个if语句判断商的正负,第二个if语句判断是否溢出;外层while循环累加res,里层while循环求满足条件的cnt和刚好大于divid的temp;
- 结果: AC
- 有问题欢迎评论,大家一起交流学习 如有错误,也请不吝赐教;
转载请注明出处及链接 谢谢