2
头图

Divide two numbers

Title description: Given two integers, dividend and divisor. Divide two numbers without using multiplication, division and mod operators.

Returns the quotient obtained by dividing the dividend by the divisor.

The result of integer division should be truncated (truncate) the decimal part, for example: truncate(8.345) = 8 and truncate(-2.7335) = -2

Please refer to LeetCode official website for example description.

Source: LeetCode
Link: https://leetcode-cn.com/problems/divide-two-integers/
The copyright belongs to Lingkou Network. For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.

Solution 1: Binary search

First, judge several special cases; then use binary search to find the divisor.

For the solution, refer to the solution on the official website of leetcode.

public class LeetCode_029 {
    /**
     * 二分查找
     *
     * @param dividend 被除数
     * @param divisor  除数
     * @return
     */
    public static int divide(int dividend, int divisor) {
        if (dividend == Integer.MIN_VALUE) {
            if (divisor == 1) {
                // 当被除数为最小值,除数为1时,直接返回最小值
                return Integer.MIN_VALUE;
            }
            if (divisor == -1) {
                // 当被除数为最小值,除数为-1时,相除会溢出,直接返回最大值
                return Integer.MAX_VALUE;
            }
        }

        if (dividend == 0) {
            // 如果被除数为0,除以任何数都为0,直接返回0
            return 0;
        }

        if (divisor == Integer.MIN_VALUE) {
            if (dividend == Integer.MIN_VALUE) {
                // 如果被除数和除数都是最小值,返回1
                return 1;
            } else {
                // 当除数是最小值,被除数不是最小值时,相除的结果肯定是在-1和1之间,返回0
                return 0;
            }
        }

        // 将所有的正数取相反数,这样就只需要考虑一种情况
        boolean rev = false;
        if (dividend > 0) {
            dividend = -dividend;
            rev = !rev;
        }
        if (divisor > 0) {
            divisor = -divisor;
            rev = !rev;
        }

        int left = 1, right = Integer.MAX_VALUE, ans = 0;
        while (left <= right) {
            // 注意溢出,并且不能使用除法
            int mid = left + ((right - left) >> 1);
            boolean check = quickAdd(divisor, mid, dividend);
            if (check) {
                ans = mid;
                // 注意溢出
                if (mid == Integer.MAX_VALUE) {
                    break;
                }
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return rev ? -ans : ans;
    }

    /**
     * 快速乘
     *
     * @param y
     * @param z
     * @param x
     * @return
     */
    public static boolean quickAdd(int y, int z, int x) {
        // x和y是负数,z是正数
        // 需要判断 z*y >= x 是否成立
        int result = 0, add = y;
        while (z != 0) {
            if ((z & 1) != 0) {
                // 需要保证 result + add >= x
                if (result < x - add) {
                    return false;
                }
                result += add;
            }
            if (z != 1) {
                // 需要保证 add + add >= x
                if (add < x - add) {
                    return false;
                }
                add += add;
            }
            // 不能使用除法
            z >>= 1;
        }
        return true;
    }

    public static void main(String[] args) {
        System.out.println(Integer.toBinaryString(10));
        System.out.println(Integer.toBinaryString(6));
        System.out.println(Integer.toBinaryString(3));
        System.out.println(divide(10, 3));
    }
}
[Daily Message] with a calm appearance, experienced the attack of smoke, rain, dust and wind, and restored the original self. Lightly embrace and laugh, deep in time, sit gently.

醉舞经阁
1.8k 声望7.1k 粉丝

玉树临风,仙姿佚貌!