• LeetCode(29) - Divide Two Integers


      这道题要求的是完成整数的除法运算,不能用乘除和mod来求。既然不能够用乘除和取模,能用的就只有加减和位移。

      思路比较抽象,直接说不好理解,举个例子,假设被除数是28,除数是5,则在第一个循环里,我们需要找到2^n满足2^n * 5 < 28,事实上我们知道,当n=2时,有4*5 = 20, n = 3时,8*5 = 40,所以我们n取2,得到28至少有4个5相加,此时28-20 = 8。重新再走循环,得到8有一个5相加,此时8-5*1=3。因为3小于5,所以循环结束,综合两次循环我们可以得到,28最多只能有4(第一次循环)+ 1(第二次循环)个5相加,所以答案就是4+1 = 5。至于2^n不用乘法怎么得到呢?—— 通过左移。

      当然还要注意一些边界条件,包括Integer.MIN_VALUE / -1的时候,得到的值会溢出等等。

      代码如下:

     1 public class Solution {
     2     public int divide(int dividend, int divisor) {
     3         //被除数为0或者Integer.MIN_VALUE / -1的情况。
     4         if (divisor == 0 || (dividend == Integer.MIN_VALUE 
     5             && divisor == -1)) return Integer.MAX_VALUE;
     6         int res = 0;
     7         //符号
     8         int sign = (dividend > 0 && divisor < 0) || (dividend < 0 && divisor > 0)? -1 : 1;
     9         //取long防止计算中溢出
    10         long a = Math.abs((long)dividend);
    11         long b = Math.abs((long)divisor);
    12         //等号不能省略。
    13         while (a >= b) {
    14             long multi = 1;
    15             long cur = b;
    16             //每次循环curr每左移一次,就等于乘以2
    17             while (a >= cur) {
    18                 cur <<= 1;
    19                 //记录2^n
    20                 multi <<= 1;
    21             }
    22             //因为上面循环超过a,故右移回去一位,
    23             cur >>= 1;
    24             multi >>= 1;
    25             a -= cur;
    26             res += (int)multi;
    27             multi = 0;
    28         }
    29         return res * sign;
    30     }
    31 }
  • 相关阅读:
    vue 生产包 背景图片-background图片不显示
    数组的方法
    前端常用Utils工具函数库合集
    vue路由
    问题
    Promise与async/await -- 处理异步
    vue中axios使用
    移动端-调试工具
    微信公众平台开发(8) 自定义菜单功能开发
    微信公众平台开发(6) 翻译功能开发
  • 原文地址:https://www.cnblogs.com/kepuCS/p/5283193.html
Copyright © 2020-2023  润新知