题目描述
给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend 除以除数 divisor 得到的商。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/divide-two-integers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
这个题目要求不能用 *
/
%
, 然后去求一个商,最暴力的想法就是去进行遍历,每一次减去一个除数,一直到被除数 小于 零 结束。
不过换一下思路,这个可以用二进制拆分的思想去解决这个问题。
我们知道,任意一个数字都可以被二进制表示,那么这个题目所求的被除数可以被几个除数表示,也同样可以进行一个二进制的拆分。
类似多重背包问题的二进制优化的思路。
首先看被除数可以表示成 2 i * 除数 + 2 j * 除数 + … … ;
然后依次求出i , j 是啥就可以了。
代码
参照大佬的实现。
class Solution {
public:
int divide(int dividend, int divisor) {
long ans = 0, up = fabs(dividend), down = fabs(divisor);
while (up > down) {
int count = 1, base = down;
while (up > (base << 1)) {
count <<= 1;
base <<= 1;
}
ans += count;
up -= base;
}
ans = ((dividend < 0) ^ (divisor < 0)) ? -ans : ans;
return (ans > INT_MAX || ans < INT_MIN) ? INT_MAX : ans;
}
};
总结
二进制拆分是很有用的一个工具,比如说用来解决这个问题。
七只老鼠,一百瓶药水,其中有一瓶是毒药,毒发时间为一天,使用一天时间检测出毒药
对100瓶毒药进行二进制编码,0000001,0000010,…,1100100
老鼠分别为A,B,C,D,E,F,G
A老鼠喝编码格式为1xxxxxx的药水
B老鼠喝编码格式为x1xxxxx的药水
C老鼠喝编码格式为xx1xxxx的药水
D老鼠喝编码格式为xxx1xxx的药水
E老鼠喝编码格式为xxxx1xx的药水
F老鼠喝编码格式为xxxxx1x的药水
G老鼠喝编码格式为xxxxxx1的药水
最后查看老鼠死亡情况,假如C和D死亡,说明0011000为毒药。
神奇。