• LeetCode: Divide Two Integers 解题报告


    Divide Two Integers


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

    SOLUTION 1
    1. 基本思想是不断地减掉除数,直到为0为止。但是这样会太慢。

    2. 我们可以使用2分法来加速这个过程。不断对除数*2,直到它比被除数还大为止。加倍的同时,也记录下cnt,将被除数减掉加倍后的值,并且结果+cnt。

    因为是2倍地加大,所以速度会很快,指数级的速度。

    3. 另外要注意的是:最小值的越界问题。对最小的正数取abs,得到的还是它。。。 因为最小的正数的绝对值大于最大的正数(INT)

    所以,我们使用Long来接住这个集合就可以了。

     1 public class Solution {
     2     public int divide(int dividend, int divisor) {
     3         long a = Math.abs((long)dividend);
     4         
     5         // ref : http://blog.csdn.net/kenden23/article/details/16986763
     6         // Note: 在这里必须先取long再abs,否则int的最小值abs后也是原值
     7         long b = Math.abs((long)divisor);
     8         
     9         int ret = 0;
    10         // 这里必须是= 因为相等时也可以减
    11         while (a >= b) {
    12             // 判断条件是 >=
    13             for (long deduce = b, cnt = 1; a >= deduce; deduce <<= 1, cnt <<= 1) {
    14                 a -= deduce;
    15                 ret += cnt;
    16             }
    17         }
    18         
    19         // 获取符号位。根据除数跟被除数的关系来定
    20         return (dividend > 0) ^ (divisor > 0) ? -ret: ret;
    21     }
    22 }
    View Code

    注意:

    1. C,java中的右移运算,是带符号位的,叫算术右移http://www.cppblog.com/tx7do/archive/2006/10/19/13867.html

    2015.1.3 redo:

    Leetcode又加强了一大堆边界条件运算,所以我们代码也要更改:

    1. 返回值的时候,判断是不是越界,越界返回最大值。

    例子:

    Input: -2147483648, -1
    Expected: 2147483647

     1 public int divide(int dividend, int divisor) {
     2         if (divisor == 0) {
     3             return Integer.MAX_VALUE;
     4         }
     5         
     6         // Note: 在这里必须先取long再abs,否则int的最小值abs后也是原值
     7         long dividendTmp = Math.abs((long)dividend);
     8         long divisorTmp = Math.abs((long)divisor);
     9         
    10         // bug 3: ret should use Long to avoid overflow.
    11         long ret = 0;
    12         // bug 2: should use dividentTmp > divisor as the while judge.
    13         while (dividendTmp >= divisorTmp) {
    14             // bug 1: should use Long for tmp.
    15             long tmp = divisorTmp;
    16             int rst = 1;
    17             while(tmp <= dividendTmp) {
    18                 // bug 3: the two statement should inside the while LOOP.
    19                 ret += rst;
    20                 dividendTmp -= tmp;
    21                 
    22                 tmp <<= 1;
    23                 rst <<= 1;
    24             }
    25         }
    26         // bug 4: out of range:
    27         /*
    28         Input:    -2147483648, -1
    29         Output:    -2147483648
    30         Expected:    2147483647
    31         */
    32         //ret = ((dividend > 0) ^ (divisor > 0)) ? -ret: ret;
    33         ret = ((((dividend ^ divisor) >> 31) & 1) == 1) ? -ret: ret;
    34         
    35         if (ret > Integer.MAX_VALUE || ret < Integer.MIN_VALUE) {
    36             return Integer.MAX_VALUE;
    37         } else {
    38             return (int)ret;
    39         }
    40     }
    View Code

    简化一点:

     1 public int divide(int dividend, int divisor) {
     2         long a = Math.abs((long)dividend);
     3         long b = Math.abs((long)divisor);
     4         
     5         long ret = 0;
     6         
     7         while (a >= b) {
     8             for (long tmp = b, cnt = 1; a >= tmp; tmp <<= 1, cnt <<= 1) {
     9                 ret += cnt;
    10                 a -= tmp;
    11             }
    12         }
    13         
    14         ret = (((dividend ^ divisor) >> 31) & 1) == 1 ? -ret: ret;
    15         if (ret > Integer.MAX_VALUE || ret < Integer.MIN_VALUE) {
    16             return Integer.MAX_VALUE;
    17         }
    18         
    19         return (int)ret;
    20     }
    View Code

    GitHub Code:

    divide.java

    Ref: http://blog.csdn.net/fightforyourdream/article/details/16899675

  • 相关阅读:
    利用FUSE编写自定义的文件系统
    ubuntu16.04 overlay 不支持redirect_dir开关
    ip rule实现源IP路由,实现一个主机多IP(或多网段)同时通(外部看是完全两个独立IP)
    段地址机制以及段地址转换触发segmentation falt
    sshfs+overlayfs实现一个共享只读资源被多个主机挂载成可写目录
    解析prototxt文件的python库 prototxt-parser(使用parsy自定义文件格式解析)
    arris1750 pandorabox安装bandwidthd之后带宽监控(nlbwmon)报资源不足
    工作中的C++问题汇总
    CMake相关代码片段
    编写合格的C代码(1):通过编译选项将特定警告视为错误
  • 原文地址:https://www.cnblogs.com/yuzhangcmu/p/4049170.html
Copyright © 2020-2023  润新知