Description
Given two integers dividend and divisor, divide two integers without using multiplication, division and mod operator.
Return the quotient after dividing dividend by divisor.
The integer division should truncate toward zero.
Example 1:
Input: dividend = 10, divisor = 3
Output: 3
Example 2:
Input: dividend = 7, divisor = -3
Output: -2
Note:
Both dividend and divisor will be 32-bit signed integers.
The divisor will never be 0.
Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−2^31, 2^31 − 1]. For the purpose of this problem, assume that your function returns 2^31 − 1 when the division result overflows.
分析
题目的意思是:给你一个除数和一个被除数,不能用乘除,求余数运算,求出结果。
可以采用位运算进行优化,即模拟计算机上的除法运算。将整数转化成二进制形式,即num = a02^0 + a12^1 + a22^2 + … + an2^n。
基于以上这个公式以及左移一位相当于乘以2,可以先让除数左移直到大于被除数之前得到一个最大的基数。然后每次用被除数去减去这个基数,同时结果增加2^k。接下来继续重新左移除数左移迭代,直到被除数不大于除数为止。因为这个方法的迭代次数是按2的幂直到结束,所以时间复杂度为O(logn)。
- 时间复杂度:O(logn)
- 空间复杂度:O(1)
C++实现
class Solution {
public:
int divide(int dividend, int divisor) {
if(divisor==0||(dividend==INT_MIN&&divisor==-1)) return INT_MAX;
long long m=abs((long long)dividend);
long long n=abs((long long)divisor);
int sign=1;
if(dividend<0^divisor<0){
sign=-1;
}
if(n==1) return m*sign;
long long res=0;
while(m>=n){
long long t=n,p=1;
while(m>=(t<<1)){
t<<=1;
p<<=1;
}
res+=p;
m-=t;
}
return res*sign;
}
};
Python实现
class Solution:
def divide(self, dividend: int, divisor: int) -> int:
INT_MIN = -2**31
INT_MAX = 2**31-1
if dividend==INT_MIN:
if divisor == 1:
return INT_MIN
if divisor == -1:
return INT_MAX
if divisor == INT_MIN:
return 1 if dividend == INT_MIN else 0
if dividend == 0:
return 0
rev = False
if dividend >0:
dividend = -dividend
rev = not rev
if divisor > 0:
divisor = - divisor
rev = not rev
candidates = [divisor]
while candidates[-1]>=dividend - candidates[-1]:
candidates.append(candidates[-1]+candidates[-1])
ans = 0
for i in range(len(candidates)-1, -1, -1):
if candidates[i]>=dividend:
ans += (1<<i)
dividend -=candidates[i]
return -ans if rev else ans
上面的解法有点难懂,我们再看下面:
class Solution:
def divide(self, a: int, b: int) -> int:
if b==0:
return 0
sign = 1
if (a<0)^(b<0):
sign=-1
a = abs(a)
b = abs(b)
quot = 0
result = 0
# 从最高位开始逐位相除
for i in range(31,-1,-1):
if result+(b<<i)<=a:
# 更新结果
result+=(b<<i)
# 更新商
quot|=(1<<i)
if sign==-1:
return max(-quot,-2**31)
return min(quot,2**31-1)
参考文献
LeetCode — 29. Divide Two Integers
[LeetCode] Divide Two Integers 两数相除