0%

lc59.两数相除

29. 两数相除

难点在于处理不能用long解决溢出问题

思路1:“二进制”减法(没有满足越界要求)

不能用除法,最简单的思路就是被除数(dividend)不断地减除数(divisor),直到减到剩余余数,相减的次数就是结果。该方法的问题就是时间复杂度太高,

  • 二进制优化,首先找到最大的n使得 $divisor 2^n < dividend$,每次减去 $ divisor 2^n, divisor 2^{n-1} ,divisor 2^{n-2} ……$,直到减到 $ divisor $
  • 实际上就是将原来的逐个减去,变为二进制减去(找商的二进制表示),由于任何数都能由二进制表示,所以该方法必定有解
  • 我的实现方法越界无法规避,只能用Long

复杂度分析:

没有分析的必要,由于只有32位整数,二进制一共只需要移动32次,时间复杂度与空间复杂度均为O(1)

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public int divide(int dividend, int divisor) {
long result = 0;
boolean isNegative = (dividend < 0 & divisor > 0) || (dividend > 0 & divisor < 0);
long temp = 1;

//首先绝对值求解
long denominator = (long)Math.abs((long)dividend);
long numerator = (long)Math.abs((long)divisor);
//首先找到最大元素
while(numerator << 1 <= denominator){
temp = temp << 1;
numerator = numerator << 1;
}
while(numerator >= Math.abs((long)divisor)){
if(denominator >= numerator){
denominator -= numerator;
if(isNegative)
result -= temp;
else
result += temp;
}
numerator = numerator >> 1;
temp = temp >> 1;
}
if(result > Integer.MAX_VALUE){
result = Integer.MAX_VALUE;
}
return (int)result;
}

思路2:条件约束+二分查找(答案的方法看得我头疼)