29. 两数相除
- 1)题目
- 2)思路
- 3)代码
- 1.初始代码
- 2.第一次优化
- 3.第二次优化
- 4)结果
- 1.初始结果
- 2.第一次优化结果
- 3.第二次优化结果
1)题目
给你两个整数,被除数 dividend
和除数 divisor
。将两数相除,要求 不使用 乘法、除法和取余运算。
整数除法应该向零截断,也就是截去(truncate
)其小数部分。例如,8.345
将被截断为 8
,-2.7335
将被截断至 -2
。
返回被除数 dividend
除以除数 divisor
得到的 商 。
注意:假设我们的环境只能存储 32 位 有符号整数,其数值范围是 [−2^31, 2^31 − 1]
。本题中,如果商 严格大于 2^(31 − 1)
,则返回 2^(31 − 1)
;如果商 严格小于 -2^31
,则返回 -2^31
。
示例 1:
输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = 3.33333… ,向零截断后得到 3 。
示例 2:
输入: dividend = 7, divisor = -3
输出: -2
解释: 7/-3 = -2.33333… ,向零截断后得到 -2 。
提示:
- -2^31 <= dividend, divisor <= 2^(31 − 1)
- divisor != 0
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/divide-two-integers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2)思路
一开始是全部转成正数,后面发现比较麻烦,就采用全部转为负数这种方案。
代码优化思路:
dividend = 100, divisor = 3
return i 1 2 4 8 16 32
divisor 3 6 12 24 48 96
dividend = 96 + 3 = 99 余1
输出:i = 32 + 1 = 33
3)代码
1.初始代码
直接循环相减
public static int divide(int dividend, int divisor) {
// ------------ 前面的代码部分 ---------------
if (dividend == 0) return 0;
// 除数为1或-1
if (divisor == 1) return dividend;
if (divisor == -1) {
if (dividend == Integer.MIN_VALUE) {
return Integer.MAX_VALUE;
}
return -dividend;
}
// 除数等于被除数
if (dividend == divisor) return 1;
// 默认为正的
boolean flag = true;
// 全部转为负数
if (dividend > 0) {
dividend = -dividend;
flag = !flag;
}
if (divisor > 0) {
divisor = -divisor;
flag = !flag;
}
// 被除数小于除数
if (dividend > divisor) return 0;
// ------------ 前面的代码部分 ---------------
// ------------ 优化的代码部分 ---------------
int i = 0;
while (!(dividend > divisor)) {
dividend -= divisor;
++i;
}
// ------------ 优化的代码部分 ---------------
return flag ? i : -i;
}
2.第一次优化
循环相减改良版
public static int divide2(int dividend, int divisor) {
// 前面的代码同上
// ------------ 优化的代码部分 ---------------
int i = 1;
int value = divisor;
while (dividend - divisor <= value) {
if (dividend - divisor <= divisor) {
divisor += divisor;
i += i;
} else {
divisor += value;
++i;
}
}
// ------------ 优化的代码部分 ---------------
return flag ? i : -i;
}
3.第二次优化
采用递归方法
public static int divide(int dividend, int divisor) {
// 前面的代码同上
// ------------ 优化的代码部分 ---------------
int i = divideValue(dividend, divisor, 0);
// ------------ 优化的代码部分 ---------------
return flag ? i : -i;
}
private static int divideValue(int dividend, int divisor, int i) {
if (dividend > divisor) return 0;
int value = divisor;
int num = 1;
while (dividend - value <= value) {
value += value;
num += num;
}
i = num + divideValue(dividend - value, divisor, i);
return i;
}