题目要求:不能用乘法、除法、模运算、不能爆int
典:边界问题,爆int,分类
一些玉玉的话:官方狗屎题解,早就看懂了但就是一直卡,我是真不习惯它的二分、并且最初边界的分类不太好懂为什么这样分。
代码笔记:
重点还是二分答案+快速乘的写法,我平常喜欢写最右的写法,所以这里的是
mid =l + ((r - l + 1)>>1)
而不是mid =l + ((r - l )>>1)
;又因为+1
计算爆int,所以l
最初值为1。根据我的二分,又把答案为0的先分类走,即if(a > b) return 0;
。
个人喜欢的分类简单容易想到的,或者是代码需要的。
二分的时候,x,y都是负数,只有z为正数,所以mid越大,result越小,比较要当心;另外,不一定会被整除,所以剔除
result + x < z
,它必不是答案。
if(y != 1){
if(x < z - x) return false; // x + x < z
x += x;
}
其实这步很有必要!!!防爆,和没必要的return 会影响结果。
class Solution {
public:
int divide(int a, int b) {
if(a == 0) return 0; //0除以任何除数都为0
if(b == 1){
return a;
}
if(b == -1)
{
if(a == INT_MIN) return INT_MAX;
return -a;
}
bool rev = 0;
if(a > 0)
{
a = -a;
rev = !rev;
}
if(b > 0)
{
b = -b;
rev = !rev;
}
auto check = [](int x, int y, int z) { //
int result = 0;
while (y) {
if(y & 1) {
if(result < z - x) return false; //result + x < z
result += x;
}
if(y != 1){
if(x < z - x) return false; // x + x < z
x += x;
}
y >>= 1;
}
return result >= z;
};
if(a > b) return 0;
int l = 1, r = INT_MAX;
while(l < r)
{
int mid =l + ((r - l + 1)>>1);
if(check(b, mid, a)) l = mid; // b * mid >= a
else
{
r = mid -1; //b * mid < a
}
}
if(rev == true)
{
l = -l;
}
return l;
}
};
还在改代码格式,写的不好。