29. 两数相除
利用加减法位运算实现除法器
29.题目链接-来源:力扣(LeetCode)
给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend 除以除数 divisor 得到的商。
整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
示例 1:
输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = truncate(3.33333..) = truncate(3) = 3
思路:
题目要求不能用乘除法,也就是几乎要我们实现一个有符号整数除法器。
我们可以参考竖式计算的思路来构造这个除法器。
- 在竖式中,我们固定被除数 dividend,依次从高到低遍历其每一位。
- 在每一轮遍历中,我们对除数 divisor 进行左移操作,直到移位后的结果「恰好」小于等于 dividend (「恰好」的意思是,若该结果继续左移 1 位,则结果会大于 dividend)。
- 用被除数 dividend 减去这个移位结果,得到的数字作为新的 dividend 进行下一轮循环,直到 dividend 小于 divisor 而停止。
以上操作默认两个操作数的符号均为正数。实际运算中,我们会碰到 被除数 和 除数 符号不一致的情况,可以记录其原始符号,转换符号一致后进行运算,最后再补回符号。
另外,本题假设环境只存储 32 位整数,为了防止结果溢出,我们可以统一把 被除数 和 除数 转换为 负数 (因为负数的表数范围比正数大 1,所以转成负数时不会溢出), 此时,对于前述循环,其涉及到的 不等关系 全都要反向(即「小于」应变为「大于」,以此类推)。
细节,题目要求特殊值,除法结果溢出(其实只有一种情况,就是 -2^31 / -1,没有对应的正数)要返回 2^31 - 1 ,也就是最大的正数,因此单独处理即可。
时间复杂度:O(1)
空间复杂度:O(1)
实现:
1 | class Solution { |
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.