[Java]剑指 Offer II 001. 整数除法

该博客主要介绍了如何解决LeetCode中的整数除法问题,通过解析题意和推演,得出利用二进制表示的解题思路。博主详细解释了如何通过逐次减法推算出商的二进制位模式,并强调了在处理有符号数时可以将其视为无符号数进行运算。在代码实现部分,博主提到了处理溢出的情况。最后,博主分享了相关资源链接。
摘要由CSDN通过智能技术生成

题意: 给定两个整数 a 和 b ,求它们的除法的商 a/b.

要求不得使用乘号 '*'、除号 '/' 以及求余符号 '%' 。除法结果应截去小数部分

此题拿到手有点懵, 分析题意就知道这道题目具体要考查的内容

 1. 思考除法的底层实现
 2. 除法? a / b = k····c, c为余数, 舍去

解题思路

锁定表达式中的: k

k是整数, 因此可以用二进制表示

由乘法反推 a 的等式:

b*k + c = a;

此题和剑指 Offer 16. 数值的整数次方相似—通过 k 的位模式累加至 a。

为了简便, 在下面的描述中, 我们把 a,b 看成无符号

由于计算机底层在处理有符号数和无符号数的加减法时, 在位模式上的行为是一致的, 只是对相同的位模式看作不同的值 ; 因此我们可以将其看成无符号数的减法来处理-----CSAPP-第三版-P74#关于整数运算的最后思考。

补充: 有符号数的最高位的权重为 -2^31; 无符号数的最高位权重为 2^31; 其他位权重一致。

那我们可以通过逐次减 b 来推得 k 的位模式吗?

推演

从 k 的最高位开始推算(权重 2^31)。

k 的最高位只能有两种情况: 0 或 1

1) **最高位为 1 时, 说明 2^31*b <= a;
2) **最高位为 0 时, 说明 2^31*b > a;

k 的剩余位和最高位同样处理, 就不再赘述

按照这个逻辑得到 k 的值后, 我们就得到了无符号数 a,b 的商 k

由于是无符号数的推算, 因此在转换成结果时, 需要进行符号化。

其他细节

题目要求截去小数部分, 我们在处理 k 的位模式的时候, 只有 0或1, 再看 a = b*k + c

其中 c < b, 当计算 k 的最低位时, 由于 1*b > c, 故最低位必定被设置为 0, 从而实现了截断

补充: 题目要求的是向 0 舍入 ---CSAPP-第三版-P73

代码实现

本题中,如果除法结果溢出,则返回 2^31 − 1 (Integer.MIN_VALUE / 1 未溢出, 所以不考虑, 其他情况更不会溢出)。

	class Solution {

		public int divide(int a, int b) {
			// 本题中,如果除法结果溢出,则返回 2^31 − 1 (Integer.MIN_VALUE / 1 未溢出, 所以不考虑, 其他情况不会溢出)
			// 常规结果仍然是最小值, 因为最小值的非就是本身
			// 0x80000000 + 0x80000000 = 0x00000000(32位截断后的值) --- 参照 CSAPP(第三版)-P66
			if (a == Integer.MIN_VALUE && b == -1) {
				return Integer.MAX_VALUE;
			}
			// 计算结果的正负
			boolean isResNegative = (a > 0) ^ (b > 0);
			// 这里如果对 Integer.MIN_VALUE 取绝对值仍然会得到本身, 参照如上
			// 取绝对值后,  0(b!=0) <= a、b <= Integer.MAX_VALUE 或 a、b == Integer.MIN_VALUE
			a = Math.abs(a);
			b = Math.abs(b);
			int result = 0;
			//这里把 a,b 当成无符号数处理, 因此强制逻辑右移( Java只支持有符号数,但是我们可以把底层位模式看成无符号数)
			for (int i = 31; i >= 0; --i) {
				// 考虑边界值:
				// a = Integer.MAX_VALUE, b = 1                  res = Integer.MAX_VALUE
				// a = Integer.MIN_VALUE, b = 1                  res = Integer.MIN_VALUE
				// a = Integer.MIN_VALUE, b = Integer.MIN_VALUE  res = 1
				if ((a >>> i) - b >= 0) {
					a -= (b << i);
					result += (1 << i);
				}

			}
			return isResNegative ? -result : result;
		}
	}

其他

本题解同步至剑指offer专项突击版仓库内, 欢迎查看。
我的力扣主页

Github仓库

Gitee仓库

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值