63
63
64
64
<!-- 这里可写通用的实现逻辑 -->
65
65
66
- 通过下面这段伪代码,不难理解除法本质上就是减法,但是一次循环只能做一次减法,效率太低会导致超时,所以再加上快速幂的思想优化即可
67
-
68
- ``` py
69
- sign = - 1 if a * b < 0 else 1
70
- a = abs (a)
71
- b = abs (b)
72
- cnt = 0
73
- while a >= b:
74
- a -= b
75
- cnt += 1
76
- return sign * cnt
77
- ```
66
+ ** 方法一:模拟 + 快速幂**
67
+
68
+ 除法本质上就是减法,题目要求我们计算出两个数相除之后的取整结果,其实就是计算被除数是多少个除数加上一个小于除数的数构成的。但是一次循环只能做一次减法,效率太低会导致超时,可借助快速幂的思想进行优化。
69
+
70
+ 需要注意的是,由于题目明确要求最大只能使用 32 位有符号整数,所以需要将除数和被除数同时转换为负数进行计算。因为转换正数可能会导致溢出,如当被除数为 ` INT32_MIN ` 时,转换为正数时会大于 ` INT32_MAX ` 。
71
+
72
+ 假设被除数为 $a$,除数为 $b$,则时间复杂度为 $O(\log a \times \log b)$,空间复杂度 $O(1)$。
78
73
79
74
<!-- tabs:start -->
80
75
@@ -85,19 +80,23 @@ return sign * cnt
85
80
``` python
86
81
class Solution :
87
82
def divide (self , a : int , b : int ) -> int :
88
- INT_MAX = (1 << 31 ) - 1
89
- INT_MIN = - (1 << 31 )
90
- sign = - 1 if a * b < 0 else 1
91
- a = abs (a)
92
- b = abs (b)
93
- tot = 0
94
- while a >= b:
95
- cnt = 0
96
- while a >= (b << (cnt + 1 )):
97
- cnt += 1
98
- tot += 1 << cnt
99
- a -= b << cnt
100
- return sign * tot if INT_MIN <= sign * tot <= INT_MAX else INT_MAX
83
+ if b == 1 :
84
+ return a
85
+ if a == - (2 ** 31 ) and b == - 1 :
86
+ return 2 ** 31 - 1
87
+ sign = (a > 0 and b > 0 ) or (a < 0 and b < 0 )
88
+ a = - a if a > 0 else a
89
+ b = - b if b > 0 else b
90
+ ans = 0
91
+ while a <= b:
92
+ x = b
93
+ cnt = 1
94
+ while x >= (- (2 ** 30 )) and a <= (x << 1 ):
95
+ x <<= 1
96
+ cnt <<= 1
97
+ a -= x
98
+ ans += cnt
99
+ return ans if sign else - ans
101
100
```
102
101
103
102
### ** Java**
@@ -107,104 +106,161 @@ class Solution:
107
106
``` java
108
107
class Solution {
109
108
public int divide (int a , int b ) {
110
- int sign = 1 ;
111
- if ((a < 0 ) != (b < 0 )) {
112
- sign = - 1 ;
109
+ if (b == 1 ) {
110
+ return a;
113
111
}
114
- long x = abs(a);
115
- long y = abs(b);
116
- long tot = 0 ;
117
- while (x >= y) {
118
- int cnt = 0 ;
119
- while (x >= (y << (cnt + 1 ))) {
120
- cnt++ ;
121
- }
122
- tot += 1L << cnt;
123
- x -= y << cnt;
112
+ if (a == Integer . MIN_VALUE && b == - 1 ) {
113
+ return Integer . MAX_VALUE ;
124
114
}
125
- long ans = sign * tot;
126
- if (ans >= Integer . MIN_VALUE && ans <= Integer . MAX_VALUE ) {
127
- return (int ) ans;
115
+ boolean sign = (a > 0 && b > 0 ) || (a < 0 && b < 0 );
116
+ a = a > 0 ? - a : a;
117
+ b = b > 0 ? - b : b;
118
+ int ans = 0 ;
119
+ while (a <= b) {
120
+ int x = b;
121
+ int cnt = 1 ;
122
+ while (x >= (Integer . MIN_VALUE >> 1 ) && a <= (x << 1 )) {
123
+ x << = 1 ;
124
+ cnt << = 1 ;
125
+ }
126
+ ans += cnt;
127
+ a -= x;
128
128
}
129
- return Integer . MAX_VALUE ;
129
+ return sign ? ans : - ans ;
130
130
}
131
+ }
132
+ ```
133
+
134
+ ### ** C++**
131
135
132
- private long abs (long a ) {
133
- if (a < 0 ) {
134
- return - a;
136
+ ``` cpp
137
+ class Solution {
138
+ public:
139
+ int divide(int a, int b) {
140
+ if (b == 1) {
141
+ return a;
135
142
}
136
- return a;
143
+ if (a == INT_MIN && b == -1) {
144
+ return INT_MAX;
145
+ }
146
+ bool sign = (a > 0 && b > 0) || (a < 0 && b < 0);
147
+ a = a > 0 ? -a : a;
148
+ b = b > 0 ? -b : b;
149
+ int ans = 0;
150
+ while (a <= b) {
151
+ int x = b;
152
+ int cnt = 1;
153
+ while (x >= (INT_MIN >> 1) && a <= (x << 1)) {
154
+ x <<= 1;
155
+ cnt <<= 1;
156
+ }
157
+ ans += cnt;
158
+ a -= x;
159
+ }
160
+ return sign ? ans : -ans;
137
161
}
138
- }
162
+ };
139
163
```
140
164
141
165
### **Go**
142
166
143
167
```go
144
168
func divide(a int, b int) int {
145
- sign := 1
146
- if a*b < 0 {
147
- sign = -1
169
+ if b == 1 {
170
+ return a
171
+ }
172
+ if a == math.MinInt32 && b == -1 {
173
+ return math.MaxInt32
148
174
}
149
175
150
- a = abs (a)
151
- b = abs (b)
152
-
153
- tot := 0
154
- for a >= b {
155
- cnt := 0
156
- for a >= (b << (cnt + 1 )) {
157
- cnt++
176
+ sign := (a > 0 && b > 0) || (a < 0 && b < 0)
177
+ if a > 0 {
178
+ a = -a
179
+ }
180
+ if b > 0 {
181
+ b = -b
182
+ }
183
+ ans := 0
184
+
185
+ for a <= b {
186
+ x := b
187
+ cnt := 1
188
+ for x >= (math.MinInt32>>1) && a <= (x<<1) {
189
+ x <<= 1
190
+ cnt <<= 1
158
191
}
159
- tot += 1 << cnt
160
- a -= b << cnt
192
+ ans += cnt
193
+ a -= x
161
194
}
162
195
163
- ans := sign * tot
164
- if ans >= math.MinInt32 && ans <= math.MaxInt32 {
196
+ if sign {
165
197
return ans
166
198
}
167
- return math. MaxInt32
199
+ return -ans
168
200
}
201
+ ```
169
202
170
- func abs (a int ) int {
171
- if a < 0 {
172
- return -a
173
- }
174
- return a
203
+ ### ** TypeScript**
204
+
205
+ ``` ts
206
+ function divide(a : number , b : number ): number {
207
+ if (b === 1 ) {
208
+ return a ;
209
+ }
210
+ if (a === - (2 ** 31 ) && b === - 1 ) {
211
+ return 2 ** 31 - 1 ;
212
+ }
213
+
214
+ const sign: boolean = (a > 0 && b > 0 ) || (a < 0 && b < 0 );
215
+ a = a > 0 ? - a : a ;
216
+ b = b > 0 ? - b : b ;
217
+ let ans: number = 0 ;
218
+
219
+ while (a <= b ) {
220
+ let x: number = b ;
221
+ let cnt: number = 1 ;
222
+
223
+ while (x >= - (2 ** 30 ) && a <= x << 1 ) {
224
+ x <<= 1 ;
225
+ cnt <<= 1 ;
226
+ }
227
+
228
+ ans += cnt ;
229
+ a -= x ;
230
+ }
231
+
232
+ return sign ? ans : - ans ;
175
233
}
176
234
```
177
235
178
- ### ** C++ **
236
+ ### ** C# **
179
237
180
- ``` cpp
181
- class Solution {
182
- public:
183
- int divide(int a, int b) {
184
- int sign = 1;
185
- if (a < 0 ^ b < 0) {
186
- sign = -1;
238
+ ``` cs
239
+ public class Solution {
240
+ public int Divide (int a , int b ) {
241
+ if (b == 1 ) {
242
+ return a ;
187
243
}
188
-
189
- auto x = abs(static_cast<long long>(a));
190
- auto y = abs(static_cast<long long>(b));
191
- auto tot = 0ll;
192
- while (x >= y) {
193
- int cnt = 0;
194
- while (x >= (y << (cnt + 1))) {
195
- ++cnt;
196
- }
197
- tot += 1ll << cnt;
198
- x -= y << cnt;
244
+ if (a == int .MinValue && b == - 1 ) {
245
+ return int .MaxValue ;
199
246
}
200
-
201
- auto ans = sign * tot;
202
- if (ans >= INT32_MIN && ans <= INT32_MAX) {
203
- return static_cast<int>(ans);
247
+ bool sign = (a > 0 && b > 0 ) || (a < 0 && b < 0 );
248
+ a = a > 0 ? - a : a ;
249
+ b = b > 0 ? - b : b ;
250
+ int ans = 0 ;
251
+ while (a <= b ) {
252
+ int x = b ;
253
+ int cnt = 1 ;
254
+ while (x >= (int .MinValue >> 1 ) && a <= (x << 1 )) {
255
+ x <<= 1 ;
256
+ cnt <<= 1 ;
257
+ }
258
+ ans += cnt ;
259
+ a -= x ;
204
260
}
205
- return INT32_MAX ;
261
+ return sign ? ans : - ans ;
206
262
}
207
- };
263
+ }
208
264
```
209
265
210
266
### ** ...**
0 commit comments