lintcode414- Divide Two Integers- medium ※

Divide two integers without using multiplication, division and mod operator.

If it is overflow, return 2147483647

Example

Given dividend = 100 and divisor = 9, return 11.

基本思想就是把除数向左移位(×2)然后与被除数比较,直到发现恰好仅次于被除数的那个值,减去该值后递归继续。

除法的答案就是每次得到shift位移后把1向左移位同样的距离,加起来。(除数向左移位,相当于(除数*1)向左移位,相当于除数*(1向左移位))。

1.这题细节非常多,主要在正负计算,计算过程int越界,答案本身int越界,除数为0的问题。数值处理的题目这几个都很重要。

2.处理越界一个简单的方法是转化为long来计算,切记这个常用方法!不过这道题最负数和-1还是不能这样解决,因为最后输出定死了int,所以这个case不能解决,要if做。

3.negative的处理学学样例,isNegative是布尔类型,直接赋值即可不要if。最后返回的时候可以用?符号来简单处理。

4.int 转 long得这样写:long a = Math.abs((long)dividend); 里面的long不加的话 -2...8会变不了正的,因为Math.abs(int)函数当输入-2...8时输出-2...8。

5. << 优先级比 <, == 高,所以可以写divisor << shift < dividend 这种。

样例代码:

    /**
     * 本参考程序来自九章算法,由 @九章算法 提供。版权所有,转发请注明出处。
     * - 九章算法致力于帮助更多中国人找到好的工作,教师团队均来自硅谷和国内的一线大公司在职工程师。
     * - 现有的面试培训课程包括:九章算法班,系统设计班,算法强化班,Java入门与基础算法班,Android 项目实战班,
     * - Big Data 项目实战班,算法面试高频题班, 动态规划专题班
     * - 更多详情请见官方网站:http://www.jiuzhang.com/?source=code
     */ 

public class Solution {
    /**
     * @param dividend the dividend
     * @param divisor the divisor
     * @return the result
     */
    public int divide(int dividend, int divisor) {
        if (divisor == 0) {
             return dividend >= 0? Integer.MAX_VALUE : Integer.MIN_VALUE;
        }
        
        if (dividend == 0) {
            return 0;
        }
        
        if (dividend == Integer.MIN_VALUE && divisor == -1) {
            return Integer.MAX_VALUE;
        }
        
        boolean isNegative = (dividend < 0 && divisor > 0) || 
                             (dividend > 0 && divisor < 0);
                             
        long a = Math.abs((long)dividend);
        long b = Math.abs((long)divisor);
        int result = 0;
        while(a >= b){
            int shift = 0;
            while(a >= (b << shift)){
                shift++;
            }
            a -= b << (shift - 1);
            result += 1 << (shift - 1);
        }
        return isNegative? -result: result;
    }
}

自己写的:

public class Solution {
    /*
     * @param dividend: the dividend
     * @param divisor: the divisor
     * @return: the result
     */
    public int divide(int dividend, int divisor) {
        // !!!处理溢出
        if (divisor == 0 || dividend == Integer.MIN_VALUE && divisor == -1){
            return Integer.MAX_VALUE;
        }
        
        if (dividend == Integer.MIN_VALUE && divisor == 1){
            return Integer.MIN_VALUE;
        }
        // !!!处理负数
        boolean isNegative = false;
        if (dividend < 0 && divisor > 0 || dividend > 0 && divisor < 0){
            isNegative = true;
        }
        long dividendL = Math.abs((long)dividend);
        long divisorL = Math.abs((long)divisor);
        
        int result = 0;
        long sum = 0;
        int currentIdx = findIdx(dividendL, divisorL);

        while (currentIdx >= 0){
            result += 1 << currentIdx;
            sum += divisorL << currentIdx;
            currentIdx = findIdx(dividendL - sum, divisorL);
        }

        return isNegative? -result : result;
    }

    // return the exact index n so divisor * 2^n <= dividend < divisor * 2^(n + 1).
    // if dividend < divisor, return -1.
    private int findIdx(long dividend, long divisor){
        int index = 0;

        while ((divisor << index) <= dividend){
            index++;
        }
        index--;

        return index;
    }
}
原文地址:https://www.cnblogs.com/jasminemzy/p/7594791.html