Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
一刷
题解:
核心是判断符号后使用bit shift以及减法。做题过程中要仔细处理各种corner case。比如:
divisor = 0
dividend 或者 divisor = Integer.MIN_vALUE
divisor = Integer.MIN_VALUE
- if dividend = Integer.MIN_VALUE, return 1
return 0
dividend = Integer.MIN_VALUE - if divisor = -1, return Integer.MAX_VALUE
- if divisor > 0, set divisor = - divisor - calculate everything in the range of negative int
Time Complexity - O(1), Space Complexity - O(1)。
public class Solution {
public int divide(int dividend, int divisor) {
if(divisor == 0) return Integer.MAX_VALUE;
if(dividend == 0) return 0;
boolean hasSameSign = (divisor>0) ^ (dividend<0);
int res = 0;
if(divisor != Integer.MIN_VALUE && dividend != Integer.MIN_VALUE){
divisor = Math.abs(divisor);
dividend = Math.abs(dividend);
for(int i=0; i<32; i++){//can be extended to binarysearch
if((dividend>>(31 - i)) >=divisor){
dividend -= (divisor<<(31 - i));
res += 1<<(31 - i);
}
}
}
else{
if(divisor == Integer.MIN_VALUE) return dividend == Integer.MIN_VALUE? 1:0;
if(divisor == -1) return Integer.MAX_VALUE;
if(divisor >0) divisor = -divisor; // dividend == Integer.MIN_VALUE
for(int i=0; i<32; i++){//can be extended to binarysearch
if((dividend>>(31 - i)) <=divisor){
dividend -= (divisor<<(31 - i));
res += 1<<(31 - i);
}
}
}
return hasSameSign? res: -res;
}
}
二刷
思路就是分别用divisor, 2divisor, 4divisor, 8divisor去试,然后找到一个最大的但是小于dividend的值。然后dividend减去它。重复该循环。注意,中间值要转成long型整数,避免Math.abs时对于corner case: Integer.MIN_VALUE和Integer.MAX_VALUE的值出现错误。
public class Solution {
public int divide(int dividend, int divisor) {
if(divisor==0 || (dividend == Integer.MIN_VALUE && divisor == -1)) return Integer.MAX_VALUE;
int sign = ((dividend<0) ^ (divisor<0))? -1:1;
long dvd = Math.abs((long)dividend);
long dvs = Math.abs((long)divisor);
long res = 0;
while(dvd>=dvs){
long temp = dvs, multiple = 1;
while(dvd>=(temp<<1)){
temp <<=1;
multiple <<= 1;
}
dvd -= temp;
res += multiple;
}
return sign==1? (int)res : (int)-res;
}
}