給定兩個 32 位有符號整數 dividend(被除數)和 divisor(除數),不使用乘法、除法、模運算,返回商。溢出返回 INT_MAX (2³¹−1)。
基本減法:while (a >= b) { a -= b; cnt++; } 太慢(O(n))。
優化:每次嘗試減去 b * 2^k(即 b << k),找到最大的 k 使得 a >= b<2^k。這相當於二進制長除法。
long long 正數運算,避免 INT_MIN 取絕對值溢出。dividend = INT_MIN, divisor = -1 → 結果 2³¹ 溢出,返回 INT_MAX。while (a >= b),內層 while (a >= (b << shift))。class Solution {
public:
int divide(int dividend, int divisor) {
if (dividend == INT_MIN && divisor == -1) return INT_MAX;
long long a = llabs((long long)dividend);
long long b = llabs((long long)divisor);
int sign = (dividend > 0) ^ (divisor > 0) ? -1 : 1;
long long res = 0;
while (a >= b) {
long long tmp = b, cnt = 1;
while (a >= (tmp << 1)) {
tmp <<= 1;
cnt <<= 1;
}
a -= tmp;
res += cnt;
}
return sign > 0 ? (int)res : (int)-res;
}
};
long long 避免 abs(INT_MIN) 未定義行為。b << k == b * 2^k。INT_MIN / -1 溢出。這題是「位運算實現算術運算」的經典練習,展示了如何用移位和減法高效模擬除法,是面試高頻考點。