给定两个整数 a 和 b ,求它们的除法的商 a/b ,要求不得使用乘号 ‘*’、除号 ‘/’ 以及求余符号 ‘%’ 。
注意:
整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231−1]。本题中,如果除法结果溢出,则返回 231 − 1
示例 1:
输入:a = 15, b = 2
输出:7
解释:15/2 = truncate(7.5) = 7
示例 2:
输入:a = 7, b = -3
输出:-2
解释:7/-3 = truncate(-2.33333…) = -2
示例 3:
输入:a = 0, b = 1
输出:0
示例 4:
输入:a = 1, b = 1
输出:1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/xoh6Oh
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
新出 java 版的剑指 offer,第一题就给我整蒙了,不用除法做除法,看了解析,敲出代码,学习思路,待再次战斗。
使用减法来代替除法,假如给定两个数字,一个 15,一个 2,那么 15 - 7 * 2 等于 1 小于 2,所以此时商得 7,但是如果数字很大,那么时间复杂度就很高,我们想要降低时间,于是使用改进版的方法:
判断被除数是不是大于除数的两倍,如果大于,在次判断是否大于四倍,以此类推,由于每次将除数翻倍,时间复杂度变成 logn 级别的,以下是分析:
首现给定两个数,由于存在溢出情况,就是当 数字等于 int 类型的最小值,并且除数等于 -1 的时候,会发生溢出,直接返回 int 类型的最大值即可
判断除数与被除数的符号,如果一正一负(neg 就等于 1)说明此时要输出负数的结果。
然后进入到本题的核心,如何求商的值。
大循环是当被除数小于除数的时候,得出的结果就是商,定义 quoi 为当前被除数大于除数的多少倍,value 为记录除数。
本题重要的是思想。
class Solution {
public int divide(int dividend, int divisor) {
if (dividend == 0x80000000 && divisor == -1) {
return Integer.MAX_VALUE;
}
int neg = 2;
if (dividend > 0) {
neg--;
dividend *= -1;
}
if (divisor > 0) {
neg--;
divisor *= -1;
}
int result = divCore(dividend, divisor);
return neg == 1 ? -result : result;
}
private int divCore(int divident, int divisor) {
int result = 0;
while (divident <= divisor) {
int quoi = 1;
int value = divisor;
while (value >= 0xc0000000 && divident <= value + value) {
quoi += quoi;
value += value;
}
result += quoi;
divident -= value;
}
return result;
}
}