LeetCode_两数相除

题目
给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend 除以除数 divisor 得到的商。

示例 1:
输入: dividend = 10, divisor = 3
输出: 3

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

思路:
思路1:通过循环用除数不断去减被除数,当被除数小于除数时,相减的次数即为商。但当被除数相当大,除数相当小时(dividend=2^31,divisor = 1)势必会消耗很多时间,最终导致超时。
思路2:位运算的效率很高,左移1位乘2,右移以为除以2,我们先可以把一个被除数除以2^n,即向右移动n位,由于该数为带符号数,起初n为31,然后不断减小n逐渐逼近除数,当dividend/2^n>=divisor,如果被除数-除数*2^n小于除数时,则2^n即为商,如果被除数-除数*2^n大于除数时,再次用上述方法循环一次。

java:
class Solution {
	public static void main(String[] args) {
		System.out.println(divide(10,3));
		System.out.println(1<<3);
	}
	public static int divide(int dividend, int divisor) {
        boolean Symbol = (dividend ^ divisor) >= 0;    //如果大于0 两数符号相同
        long _dividend = (Math.abs((long)dividend));
        long _divisor = (Math.abs((long)divisor));
        
        if(dividend == Integer.MIN_VALUE && divisor == -1){
            return Integer.MAX_VALUE;
        }    //int最小值为2^31,除以-1就是2^31,但int最大取值2^31-1,会导致溢出
        int result = 0;
        for(int i = 31;i>=0;i--){
            if((_dividend>>i)>=_divisor){
                result = result + (1<<i);
                _dividend = _dividend - (_divisor<<i);
            }
        }
        if(Symbol == true){
            return result;
        }
        else
            return -result;
    }
}

坑:

1.long _dividend = ((long)Math.abs(dividend)); 起初将long写在了Math外面导致在求绝对值时就已经溢出了,应该改为long _dividend = (Math.abs((long)dividend));

猜你喜欢

转载自blog.csdn.net/w819104246/article/details/92390817
今日推荐