29. 两数相除
题目描述:给你两个整数,被除数
dividend和除数divisor。将两数相除,要求 不使用 乘法、除法和取余运算。整数除法应该向零截断,也就是截去(
truncate)其小数部分。例如,8.345将被截断为8,-2.7335将被截断至-2。返回被除数
dividend除以除数divisor得到的 商 。注意:假设我们的环境只能存储 32 位 有符号整数,其数值范围是
[−231, 231 − 1]。本题中,如果商 严格大于231 − 1,则返回231 − 1;如果商 严格小于-231,则返回-231。示例 1:
输入: dividend = 10, divisor = 3 输出: 3 解释: 10/3 = 3.33333.. ,向零截断后得到 3 。示例 2:
输入: dividend = 7, divisor = -3 输出: -2 解释: 7/-3 = -2.33333.. ,向零截断后得到 -2 。提示:
-231 <= dividend, divisor <= 231 - 1
divisor != 0
代码思路:
-  边界检查 :如果被除数( dividend)为0,直接返回0,因为0除以任何数都是0
-  特殊情况处理: 如果被除数是 Integer.MIN_VALUE(-2^31),并且除数是-1,直接返回Integer.MAX_VALUE,因为除以-1会导致溢出
-  确定结果的符号: 利用异或操作 ^,如果两个数的符号不同,结果为负
-  转换为长整型并取绝对值: 要处理可能超出整数范围的情况,将被除数和除数都转换为长整型,并取绝对值 
-  进行除法操作: 使用一个循环从最高位开始,逐步检查被除数是否大于或等于除数的2的幂(2^n * 除数);如果是,那么将结果加上2的n次幂,并从被除数中减去2的n次幂乘以除数,这样循环直到检查完所有 
这种方法的思路是通过逐步减去2的n次幂乘以除数来模拟除法过程,而不是使用传统的除法操作。
class Solution {public int divide(int dividend, int divisor) {if (dividend == 0) return 0;if (dividend == Integer.MIN_VALUE && divisor == -1) return Integer.MAX_VALUE;boolean flag = (dividend ^ divisor) < 0;long a = Math.abs(dividend);long b = Math.abs(divisor);int ans = 0;for (int i = 31; i >= 0; i--) {if ((a >> i) >= b) {ans += 1 << i;a -= b << i;}}if (flag) return -ans;else return ans;}
}核心代码分析:
if ((a >> i) >= b) {ans += 1 << i;a -= b << i;
}
-  检查被除数是否足够大: ① a >> i:这是一个右移操作,它将被除数 a 向右移动i位。是在检查 a 是否大于或等于b的2的i次幂,也就是2^i * b;②(a >> i) >= b:如果被除数a右移i位后仍大于或等于b,说明2^i * b是 a 的一个有效的部分
-  更新结果: ③ ans += 1 << i;:如果2^i * b是 a 的有效部分,将结果ans增加2^i,记录 a 中有多少个 b
-  更新被除数: ④ a -= b << i;:这是两步操作的结果,首先,b << i计算出2^i * b,然后这个值从 a 中减去,模拟实际的除法过程