力扣LeetCode第29题:两数相除,beat100%解法

打印 上一主题 下一主题

主题 245|帖子 245|积分 735

思路
   官方题解中有快速乘,那当然也就有快速除。思路就是模拟手动盘算除法,二进制的除法和十进制也非常类似  解题过程
   (1)起主要把除数和被除数“对齐” (2)然后除数和被除数举行比力,假如小于被除数则这一位商0,否则商1 (3)把每一位的01组装起来就是最终的结果 里面的一些边界题目还必要注意处理惩罚一下。  复杂度
时间复杂度: O(logN),其中N为被除数和除数倍数差,也即商。logN即为被除数和除数二进制的位数差,好比1011111/11,那么logN为7−2=5
空间复杂度: O(1)
  1. class Solution {
  2.     public int divide(int dividend, int divisor) {
  3.         //如果除数是最小的int
  4.         if(divisor == Integer.MIN_VALUE){
  5.             return dividend == divisor?1:0;
  6.         }
  7.         //注意最小的int为-2^31,最大的int为2^31-1,如果商为2^31,越界,应返回2^31-1
  8.         if(dividend == Integer.MIN_VALUE){
  9.             if(divisor == 1){
  10.                 return dividend;
  11.             }
  12.             if(divisor == -1){
  13.                 return Integer.MAX_VALUE;
  14.             }
  15.         }
  16.         //为了便于统一进行移位等操作,都转成正数来处理
  17.         //如果dividend == Integer.MIN_VALUE,为了避免边界问题,先加上一个除数的绝对值,保证不越界
  18.         //如果加上了绝对值,后面商的绝对值需要+1,所以设置一个标志位
  19.         boolean plusOne = false;
  20.         if(dividend == Integer.MIN_VALUE){
  21.             dividend = dividend + (divisor>0?divisor:-divisor);
  22.             plusOne = true;
  23.         }
  24.         //都转为正数处理
  25.         boolean changeSymbol = false;
  26.         if(divisor < 0){
  27.             divisor = -divisor;
  28.             changeSymbol = !changeSymbol;
  29.         }
  30.         if(dividend < 0){
  31.             dividend = -dividend;
  32.             changeSymbol = !changeSymbol;
  33.         }
  34.         //不断把除数进行左移,直到和被除数对齐
  35.         int move = 0;
  36.         int constant = (1<<30);
  37.         while(divisor < dividend){
  38.             //如果符号位后紧接的一位,也就数字位的最高位已经为1了,则不应该再左移了
  39.             if( (divisor & constant) > 0){
  40.                 break;
  41.             }
  42.             divisor <<= 1;
  43.             move++;
  44.         }
  45.         // int move = Integer.numberOfLeadingZeros(divisor) - Integer.numberOfLeadingZeros(dividend);
  46.         // divisor <<= move;
  47.         
  48.         //模拟手算除法的过程,无非是二进制而已。十进制每一位可以商0-9,二进制中只能商0或1
  49.         int ans = 0;
  50.         for(int i = move;i>=0;i--){
  51.             if(dividend < divisor){
  52.                 divisor >>= 1;
  53.             }else{
  54.                 ans += (1 << i);
  55.                 dividend -= divisor;
  56.                 divisor >>= 1;
  57.             }
  58.         }
  59.         ans = plusOne?ans+1:ans;
  60.         return changeSymbol?-ans:ans;
  61.     }
  62. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

梦应逍遥

高级会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表