โจทย์ปัญหา
ได้รับจำนวนเต็มสองจำนวน dividend และ divisor ให้หาร dividend ด้วย divisor โดยไม่ใช้การคูณ การหาร และ modulo คืนค่าผลหาร (Quotient) โดยปัดทศนิยมเข้าสู่ศูนย์
ตัวอย่าง
นำเข้า: dividend = 7, divisor = -3
ผลลัพธ์: -2
แนวคิดการแก้ปัญหา (Bit Manipulation)
ใช้หลักการ Binary Long Division โดยการเลื่อนบิต (Bit Shifting) เพื่อหาตัวคูณที่ใหญ่ที่สุดของ divisor ที่ยังน้อยกว่าหรือเท่ากับ dividend
- จัดการกรณีพิเศษ: overflow (INT_MIN / -1)
- แปลงเป็นค่าสัมบูรณ์ (ใช้
long longป้องกัน overflow) - วนลูปจนกว่า dividend < divisor:
- หา
pใหญ่สุดที่ทำให้divisor << p <= dividend - ลบ
divisor << pออกจาก dividend - บวก
1 << pเข้าไปในคำตอบ
- หา
- ปรับเครื่องหมายตาม dividend และ divisor เดิม
โค้ดตัวอย่าง (C++)
#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
class Solution {
public:
int divide(int l, int y) {
if (l == INT_MIN && y == -1) return INT_MAX; // Overflow case
lli a = labs(l);
lli b = labs(y);
lli ans = 0;
while (a - b >= 0) {
int x = 0;
while (a - (b << 1 << x) >= 0) {
x++;
}
a -= b << x;
ans += 1 << x;
}
return ((l > 0) == (y > 0)) ? ans : -ans;
}
};
int main() {
Solution ob;
cout << ob.divide(40, 3);
return 0;
}
ผลลัพธ์
13
คำอธิบายเพิ่มเติม
- ความซับซ้อนด้านเวลา: O(log n) (n = dividend)
- ใช้
long longเพื่อป้องกัน overflow เมื่อทำlabs(INT_MIN) - กรณี
INT_MIN / -1ต้องจัดการแยกเพราะผลลัพธ์เกินINT_MAX