zoukankan      html  css  js  c++  java
  • [Math]Divide Two Integers

    otal Accepted: 54356 Total Submissions: 357733 Difficulty: Medium

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

    If it is overflow, return MAX_INT.

    1.除法转换为加法,加法转换为乘法,y个x相加的结果就是x*y.

    假设结果为dividend的一半,用此值与divisor相乘,如果相乘结果大于dividend则,high=dividend,然后继续二分

    /**
    两个整数相除也可能会溢出,最小负数除以-1就溢出了
    */
    class Solution {
    public:
        long long int multiply(long long x,long long int y)
        {
            if(y==1){
                return x;
            }
            long long int res = multiply(x,y>>1);
            res = (1&y) ? (res<<1) + x: (res<<1);
            return res;
        }
        
        int divide(int dividend, int divisor) {
            long long int l_dividend = fabs(dividend);
            long long int l_divisor = fabs(divisor);    
            
            if(l_dividend < l_divisor){
                return 0;
            }
            if((dividend==INT_MIN && divisor==-1) || divisor==0){
                return INT_MAX;
            }
            
            int sign =  ((dividend>>31)^(divisor>>31)) ? -1:1;
        
            long long int low = 1,high =l_dividend;
           
            while(low<=high){
                long long int  mid = low+((high-low)>>1);
                long long int res = multiply(l_divisor,mid);
                if(res == l_dividend){
                    return mid*sign;
                }else if(res<l_dividend){
                    low = mid+1;
                }else{
                    high = mid-1;
                }
            }
            
            return (low-1)*sign;
        }
    };
     
    2.除法分配率:a/b = (x+y)/b = x/b+y/b ,其中a=x+y;
    42/6;
    dividend = 42,divisor=6;
    42 = 6*2*2 + 18  ---> 42/6 = 24/6 + 18/6
    18 = 6*2 + 6;     ----> 18/6 = 12/6 + 6
    6 = 6+0;            ---->  6/6  = 6/6 + 0
    所以:42/6 = 2*2+2+1=7;
     
    /**
    两个整数相除也可能会溢出,最小负数除以-1就溢出了
    */
    class Solution {
    public:
        int divide(int dividend, int divisor) {
            long long int l_dividend = fabs(dividend);
            long long int l_divisor = fabs(divisor);    
            
            if(l_dividend < l_divisor){
                return 0;
            }
            if((dividend==INT_MIN && divisor==-1) || divisor==0){
                return INT_MAX;
            }
            
            int sign =  ((dividend>>31)^(divisor>>31)) ? -1:1;
            int res = 0;
            while(l_dividend >= l_divisor){
                long long int tmp = l_divisor;
                int occur_times = 0;
                while(tmp <= l_dividend){
                    tmp = tmp<<1;
                    occur_times++;
                }
                res += (1<<(occur_times-1));
                l_dividend -= (tmp>>1);
            }
    
            return res*sign;
        }
    };
     
  • 相关阅读:
    Python自动化之面向对象进阶
    Python自动化之pickle和面向对象初级篇
    Python自动化之常用模块
    剑指offer 顺时针打印矩阵
    剑指 offer 树的子结构
    剑指offer 合并两个排序的链表
    剑指offer 调整数组顺序使奇数位于偶数前面
    剑指offer 数值的整数次方
    变态跳台阶
    剑指offer 重建二叉树
  • 原文地址:https://www.cnblogs.com/zengzy/p/5043519.html
Copyright © 2011-2022 走看看