【Leetcode】【中等】29.两数相除

给你两个整数,被除数 dividend 和除数 divisor。将两数相除,要求 不使用 乘法、除法和取余运算。

整数除法应该向零截断,也就是截去(truncate)其小数部分。例如,8.345 将被截断为 8 ,-2.7335 将被截断至 -2 。

返回被除数 dividend 除以除数 divisor 得到的  。

注意:假设我们的环境只能存储 32 位 有符号整数,其数值范围是 [−2^31,  2^31 − 1] 。本题中,如果商 严格大于 2^31 − 1 ,则返回 2^31 − 1 ;如果商 严格小于 -2^31 ,则返回 -2^31 。

示例 1:

输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = 3.33333.. ,向零截断后得到 3 。

示例 2:

输入: dividend = 7, divisor = -3
输出: -2
解释: 7/-3 = -2.33333.. ,向零截断后得到 -2 。

思路1 暴力解法

简单地使用循环,取x、y的绝对值,让x - y,直到不能再减,这会超出时间限制。

思路2 幂运算

前置知识

1、二进制右移一位,相当于乘以2。

2、负数的范围比正数大1,如果直接使用int类型,就有可能发生溢出。

      例如-2147483648 / -1,正确结果应该为2147483648,但是int类型数值范围是 [−2^31,  2^31 − 1] ,即为[-2147483648,2147483647],发生溢出,所以使用long类型。

举个例子

例如39 / 3 = 13

其中13二进制形式为00001101,右移一位为00011010,即乘以2,等于26。

目标 39 - 13 *  2 ^ 1 = 13

        13 - 13 * 2 ^ 0 = 0

结果 2^1 + 2 ^ 0 = 3

【Leetcode】【中等】29.两数相除_第1张图片

代码

class Solution {
    public int divide(int x, int y) {
       if (x == Integer.MIN_VALUE && y == -1) {
			return Integer.MAX_VALUE;
		}
		
        boolean sign = (x > 0 && y < 0) || (x < 0 && y > 0);
        
        long lx = Math.abs((long)x);
        long ly = Math.abs((long)y);
       
        
        long res = 0;
        while (lx >= ly) {
        	long tmp = ly, multiple = 1;
        	while (lx >= (tmp << 1)) {
        		tmp <<= 1;
        		multiple <<= 1;
        	}
        	res += multiple;
        	lx -= tmp;
        }
        
        if (sign) 
        	return (int)(-res);
        
        return (int)res;
    }
}

过程 

【Leetcode】【中等】29.两数相除_第2张图片

你可能感兴趣的:(Leetcode,leetcode,算法,职场和发展)