返回

深入浅出:算法 LeetCode 300 题之 29 两数相除

前端

一、题目

给定两个整数 dividenddivisor,计算这两个整数相除后的结果。

说明

  • dividend 是被除数,divisor 是除数。
  • 两个数均为 32 位有符号整数
  • 返回除法结果 ,该结果也必须是 32 位有符号整数。
  • 不能使用 C++ 库函数 divmod

示例 1:

输入:dividend = 10, divisor = 3
输出:3

示例 2:

输入:dividend = 7, divisor = -3
输出:-2

二、解法总览(思维导图)

为了帮助您更好地理解解法的整体思路,我们提供了一张思维导图。思维导图将各种解法清晰地展现出来,方便您快速浏览和比较。

[思维导图]

三、全部解法

接下来,我们将详细介绍每种解法的具体实现。每种方案都会提供相应的代码示例。

方案 1

思路

这种方法是利用 long long 数据类型来存储计算结果,确保不会溢出。具体而言,我们先计算出商 quotient 和余数 remainder,然后将 quotient 返回作为最终结果。需要注意的是,如果 dividenddivisor 同号,则 quotient 为正;如果 dividenddivisor 异号,则 quotient 为负。

代码

class Solution {
public:
    int divide(int dividend, int divisor) {
        if (divisor == 0) {
            return INT_MAX;
        }
        long long dividend_ll = dividend;
        long long divisor_ll = divisor;
        long long quotient = dividend_ll / divisor_ll;
        return quotient;
    }
};

方案 2

思路

这种方法使用 二分法 来快速计算商。具体而言,我们首先判断 dividenddivisor 的符号,然后将它们转为正数。接下来,我们将二分查找一个数 mid,使得 mid * divisor 接近于 dividend。最后,我们返回 mid 作为商。

代码

class Solution {
public:
    int divide(int dividend, int divisor) {
        if (divisor == 0) {
            return INT_MAX;
        }
        bool negative = (dividend > 0 && divisor < 0) || (dividend < 0 && divisor > 0);
        long long dividend_ll = abs((long long)dividend);
        long long divisor_ll = abs((long long)divisor);
        long long quotient = 0;
        while (dividend_ll >= divisor_ll) {
            long long temp = divisor_ll;
            long long i = 1;
            while (dividend_ll >= temp) {
                dividend_ll -= temp;
                quotient += i;
                i <<= 1;
                temp <<= 1;
            }
        }
        return negative ? -quotient : quotient;
    }
};

方案 3

思路

这种方法使用 位运算 来快速计算商。具体而言,我们首先判断 dividenddivisor 的符号,然后将它们转为正数。接下来,我们将 dividenddivisor 的二进制表示进行右移,直到 dividend 小于 divisor。最后,我们将右移的次数作为商。

代码

class Solution {
public:
    int divide(int dividend, int divisor) {
        if (divisor == 0) {
            return INT_MAX;
        }
        bool negative = (dividend > 0 && divisor < 0) || (dividend < 0 && divisor > 0);
        int dividend_abs = abs(dividend);
        int divisor_abs = abs(divisor);
        int quotient = 0;
        while (dividend_abs >= divisor_abs) {
            int temp = divisor_abs;
            int i = 1;
            while (dividend_abs >= temp) {
                dividend_abs -= temp;
                quotient += i;
                i <<= 1;
                temp <<= 1;
            }
        }
        return negative ? -quotient : quotient;
    }
};

四、总结

在这篇文章中,我们详细介绍了 LeetCode 第 29 题——两数相除的解法。我们从题目开始,然后提供了解法总览思维导图,再逐步深入到每种解法的具体实现,包括代码示例。希望这些信息对您有所帮助。如果您还有其他问题或建议,欢迎随时提出!