LeetCode 28 Divide Two Integers

来源:互联网 发布:java 时间轴数据 编辑:程序博客网 时间:2024/06/14 19:32

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

思路:1.先将被除数和除数转化为long的非负数,注意一定要为long,因为Integer.MIN_VALUE的绝对值超出了Integer的范围。

          2.常理:任何正整数num都可以表示为num=2^a+2^b+2^c+...+2^n,故可以采用2^a+2^b+2^c+...+2^n来表示商,即dividend=divisor*(2^a+2^b+2^c+...+2^n),(a,b,c,....m互不相等,且最大为31,最小为0)。而商的最大值为Integer.MIN_VALUE的绝对值,商最多有32个2的指数次相加,故时间复杂度为常数。

          3.divisor*2^a用计算机表示为divisor<<a;

          注意:若每次只加一个divisor,则面对Integer.MAX_VALUE除以一个很小的常数(eg:1,2,3),会超时。

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. public class Solution {  
  2.     public int divide(int dividend, int divisor) {  
  3.   
  4.         boolean positive = true;  
  5.         if((dividend>0&&divisor<0)||(dividend<0&&divisor>0))  
  6.             positive = false;  
  7.         long did=dividend>=0?(long)dividend:-(long)dividend;  
  8.         long dis=divisor>=0?(long)divisor:-(long)divisor;  
  9.   
  10.         long quotients = positiveDivide(did, dis);  
  11.         if (!positive)  
  12.             return (int)-quotients;  
  13.         return (int)quotients;  
  14.     }  
  15.   
  16.     public long positiveDivide(long did, long dis) {  
  17.         long[] array = new long[32];  
  18.         long sum = 0;  
  19.         int i = 1;  
  20.         long quotients = 0;  
  21.         if(dis==1return did;//为了避免-did=Integer.MIN_VALUE,而dis=1,出现问题  
  22.         for (array[0]=dis; i < 32 && array[i - 1] <= did; i++)   
  23.             array[i] = array[i - 1] << 1;  
  24.           
  25.         for (i = i - 2; i >= 0; i--) {  
  26.             if (sum <= did - array[i]) {  
  27.                 sum += array[i];  
  28.                 quotients += 1 << i;  
  29.             }  
  30.         }         
  31.         return quotients;  
  32.     }  
  33. }  

优化版,减小内存的消耗,不申请动态数组

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. public class Solution {  
  2.     public int divide(int dividend, int divisor) {  
  3.   
  4.         boolean positive = true;  
  5.         if((dividend>0&&divisor<0)||(dividend<0&&divisor>0))  
  6.             positive = false;  
  7.         long did=dividend>=0?(long)dividend:-(long)dividend;  
  8.         long dis=divisor>=0?(long)divisor:-(long)divisor;  
  9.   
  10.         long quotients = positiveDivide(did, dis);  
  11.         if (!positive)  
  12.             return (int)-quotients;  
  13.         return (int)quotients;  
  14.     }  
  15.       
  16.     public long positiveDivide(long did, long dis) {  
  17.         long sum = 0;  
  18.         long quotients = 0;  
  19.         if(dis==1return did;//为了避免-did=Integer.MIN_VALUE,而dis=1,出现问题  
  20.           
  21.         //sum从divisor*2^31的开始加起,不能加则试试加上divisor*2^30,  
  22.         //若不能则试试divisor*2^29,依此类推  
  23.         for (int i = 31; i >= 0; i--) {  
  24.             long temp=dis<<i;//该式为divisor*2^a  
  25.               
  26.              /* sum+temp <= dividend , 则说明dividend大于divisor*(2^m+...+2^i),m最大为31。
  27. 么2的i次方这个结果可以保留。*/
  28.             if (sum <= did - temp) {  
  29.                 sum += temp;  
  30.                 quotients += 1 << i;//2^i  
  31.             }  
  32.         }         
  33.         return quotients;  
  34.     }  
  35. }  
0 0
原创粉丝点击