本文主要是介绍将两数相除,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
将两数相除,要求 不使用 乘法、除法和取余运算。
整数除法应该向零截断,也就是截去(truncate
)其小数部分。例如,8.345
将被截断为 8
,-2.7335
将被截断至 -2
。
首先对被除数和除数为特殊值时出现越界问题进行判断。
当被除数为 32 位有符号整数的最小值 −2^31时:
如果除数为 1,那么我们可以直接返回答案 −2^31
如果除数为 −1,那么答案为 2^31,产生了溢出。此时我们需要返回 2^31−1
当除数为 32 位有符号整数的最小值 −2^31时:
如果被除数同样为 −2^31 ,那么我们可以直接返回答案 1;
对于其余的情况,我们返回答案 0。
当被除数为 0 时,我们可以直接返回答案 0。
本题最易思考出来的解法为减法暴力求解,但是由于会超时,故选择二分查找法。
class Solution {
public:int divide(int dividend, int divisor) {// 考虑被除数为最小值的情况if (dividend == INT_MIN) {if (divisor == 1) {return INT_MIN;}if (divisor == -1) {return INT_MAX;}}// 考虑除数为最小值的情况if (divisor == INT_MIN) {return dividend == INT_MIN ? 1 : 0;}// 考虑被除数为 0 的情况if (dividend == 0) {return 0;}// 一般情况,使用二分查找// 将所有的正数取相反数,这样就只需要考虑一种情况bool rev = false;if (dividend > 0) {dividend = -dividend;rev = !rev;}if (divisor > 0) {divisor = -divisor;rev = !rev;}// 快速乘auto quickAdd = [](int y, int z, int x) {// x 和 y 是负数,z 是正数// 需要判断 z * y >= x 是否成立int result = 0, add = y;while (z) {if (z & 1) {// 需要保证 result + add >= xif (result < x - add) {return false;}result += add;}if (z != 1) {// 需要保证 add + add >= xif (add < x - add) {return false;}add += add;}// 不能使用除法z >>= 1;}return true;};int left = 1, right = INT_MAX, ans = 0;while (left <= right) {// 注意溢出,并且不能使用除法int mid = left + ((right - left)>>1);bool check = quickAdd(divisor, mid, dividend);if (check) {ans = mid;// 注意溢出if (mid == INT_MAX) {break;}left = mid + 1;}else {right = mid - 1;}}return rev ? -ans : ans;}
};
这篇关于将两数相除的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!