forked from kamyu104/LintCode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdivide-two-integers.cpp
122 lines (111 loc) · 2.85 KB
/
divide-two-integers.cpp
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Time: O(logn)
// Space: O(1)
// Only using integer type.
class Solution {
public:
/**
* @param dividend the dividend
* @param divisor the divisor
* @return the result
*/
int divide(int dividend, int divisor) {
// Handle corner case.
if (divisor == INT_MIN) {
return dividend == divisor ? 1 : 0;
} else if (!divisor || divisor == -1 && dividend == INT_MIN) {
return INT_MAX;
} else if (divisor == 1) {
return dividend;
}
bool negative = (dividend > 0) ^ (divisor > 0);
if (dividend > 0) {
dividend = -dividend;
}
if (divisor > 0) {
divisor = -divisor;
}
int product = divisor;
int idx = 1;
while (product < 0 && idx < 32) {
++idx;
product <<= 1;
}
idx -= 2; // Skip value of INT_MIN
product = divisor << idx;
int multiplier = 1 << idx;
int res = 0;
while (dividend <= divisor) {
if (dividend <= product) {
res += multiplier;
dividend -= product;
}
--idx;
product = divisor << idx;
multiplier >>= 1;
}
return negative ? -res : res;
}
};
// Time: O(logn)
// Space: O(1)
// Using long long type.
class Solution2 {
public:
/**
* @param dividend the dividend
* @param divisor the divisor
* @return the result
*/
int divide(int dividend, int divisor) {
long long result = 0, dvd = llabs(dividend), dvs = llabs(divisor);
long long inc = dvs;
long long multiplier = 1;
int i = 0;
while (dvd >= inc) {
inc <<= 1;
multiplier <<= 1;
++i;
}
while (inc && i >= 0) {
while (dvd >= inc) {
dvd -= inc;
result += multiplier;
}
inc >>= 1;
multiplier >>= 1;
--i;
}
if ((dividend > 0 && divisor < 0) || (dividend < 0 && divisor > 0)) {
return -result;
} else {
return min(result, static_cast<long long>(INT_MAX));
}
}
};
// Time: O(1)
// Space: O(1)
// a / b = exp^(ln(a) - ln(b))
class Solution3 {
public:
/**
* @param dividend the dividend
* @param divisor the divisor
* @return the result
*/
int divide(int dividend, int divisor) {
if (dividend == 0) {
return 0;
}
if (divisor == 0) {
return INT_MAX;
}
long long res = exp(log(fabs(dividend)) - log(fabs(divisor)));
if ((dividend < 0) ^ (divisor < 0)) {
res = -res;
}
if (res > INT_MAX) {
res = INT_MAX;
}
return res;
}
};