

最容易想到的是通过减法代替除法,但是会超时
class Solution { public int divide(int a, int b) { if(a == 0)return 0; int symbolNum = (a>0)^(b>0)? -1:1 ;//可以对下面的代码段进行优化 /* int symbolNum = 1; if(a>0&&b>0 || a<0&&b<0) symbolNum = 1; else{ symbolNum = -1; }*/ if(a==Integer.MIN_VALUE && b==-1) return Integer.MAX_VALUE; if(a>0)a = -a; if(b>0)b = -b; int ans = 0; while(a <= b){ a -= b; ans++; } return symbolNum == -1? -ans:ans; }}不使用减法那种被除数对除数一次一次减的形式(在被除数过大而除数很小的情况下会超时),而是试图减2个、4个、8个....找到最大的2的n次方。将被除数减去除数的2的n次方倍,然后将剩余的被除数重复前面的步骤。
例如:
为了求得15/2的商,先从15里减去8 (23),得到7;再从7里减去4(22),得到3;再从3里减去2(2^1),得到1,此时1小于2,因此商是3+2+1=7。
在计算两个负数的除法时,防止每次计算除数的2倍,会导致大数溢出,要保证计算2倍之后的数大于(-231)/2。如果时计算两个正数的除法,要保证计算2倍之后的数小于(231-1)/2。
class Solution { public int divide(int a, int b) { //int 型整数的除法只有一种情况会导致溢出,即(-2^31)/(-1) if(a==Integer.MIN_VALUE && b==-1) return Integer.MAX_VALUE; if(a == 0 || b == 1)return a; else if(b == -1) return -a; int symbolNum = (a>0)^(b>0)? -1:1 ; // 由于(-2^31) 转换为正数会溢出,但是任意正数转换为负数都不会溢出 // 故,记录负数的个数,并将正数转换为负数方便统一计算 if(a>0)a = -a; if(b>0)b = -b; // while(a <= b){//这样写确实可以过案例,但是会超时 // a -= b; // ans++; // } if(a == b)return symbolNum == -1? -1:1; int ans = 0; while(a<=b){//小于是因为现在a,b都是负数 int value = b;//统计最多有几个减数(2的n次方个) int tmpQuotient = 1; while(value + value > Integer.MIN_VALUE && value + value >= a){//减到不够了为止 value += value; tmpQuotient += tmpQuotient; } ans +=tmpQuotient; a -= value; } return symbolNum == -1? -ans:ans; } }但上述代码只通过了700+样例,找了半天发现是value + value > Integer.MIN_VALUE这里出问题了,要改成value >0xc0000000。(0xc0000000是Integer.MIN_VALUE的一半)
class Solution { public int divide(int a, int b) { //int 型整数的除法只有一种情况会导致溢出,即(-2^31)/(-1) if(a==Integer.MIN_VALUE && b==-1) return Integer.MAX_VALUE; if(a == 0 || b == 1)return a; else if(b == -1) return -a; int symbolNum = (a>0)^(b>0)? -1:1 ; // 由于(-2^31) 转换为正数会溢出,但是任意正数转换为负数都不会溢出 // 故,记录负数的个数,并将正数转换为负数方便统一计算 if(a>0)a = -a; if(b>0)b = -b; // while(a <= b){//这样写确实可以过案例,但是会超时 // a -= b; // ans++; // } if(a == b)return symbolNum == -1? -1:1; int ans = 0; while(a<=b){//小于是因为现在a,b都是负数 int value = b;//统计最多有几个减数(2的n次方个) int tmpQuotient = 1; while(value >0xc0000000 && value + value >= a){//减到不够了为止 value += value; tmpQuotient += tmpQuotient; } ans +=tmpQuotient; a -= value; } return symbolNum == -1? -ans:ans; } }这里补充一下int 类型数据的最大值,最小值及其十六进制表示方式:
在int类型(32位)中:
正整数的最大值为 0x7fffffff 也就是十进制的 2147483647
正整数的最小值为 0x00000001 也就是十进制的 1
0表示为:0x00000000
负整数的最大值为 0xffffffff 也就是十进制的 -1
负整数的最小值为 0x80000000 也就是十进制的 -2147483648