深圳小提琴制作南京seo招聘
剑指offer 两数相除
题目要求:不能用乘法、除法、模运算、不能爆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 < zx += x;
}
其实这步很有必要!!!防爆,和没必要的return 会影响结果。
class Solution {
public:int divide(int a, int b) {if(a == 0) return 0; //0除以任何除数都为0if(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 < zresult += x;}if(y != 1){if(x < z - x) return false; // x + x < zx += 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 >= aelse {r = mid -1; //b * mid < a}}if(rev == true){l = -l;} return l;}
};
还在改代码格式,写的不好。