Skip to content

Commit ba7bb98

Browse files
authored
feat: add solutions to lc/lcof2 problems (doocs#2066)
* lc No.0029.Divide Two Integers * lcof2 No.001.Divide Two Integers
1 parent c73a8fb commit ba7bb98

File tree

16 files changed

+729
-471
lines changed

16 files changed

+729
-471
lines changed

lcof2/剑指 Offer II 001. 整数除法/README.md

Lines changed: 149 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -63,18 +63,13 @@
6363

6464
<!-- 这里可写通用的实现逻辑 -->
6565

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)$。
7873

7974
<!-- tabs:start -->
8075

@@ -85,19 +80,23 @@ return sign * cnt
8580
```python
8681
class Solution:
8782
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
101100
```
102101

103102
### **Java**
@@ -107,104 +106,161 @@ class Solution:
107106
```java
108107
class Solution {
109108
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;
113111
}
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;
124114
}
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;
128128
}
129-
return Integer.MAX_VALUE;
129+
return sign ? ans : -ans;
130130
}
131+
}
132+
```
133+
134+
### **C++**
131135

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;
135142
}
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;
137161
}
138-
}
162+
};
139163
```
140164
141165
### **Go**
142166
143167
```go
144168
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
148174
}
149175
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
158191
}
159-
tot += 1 << cnt
160-
a -= b << cnt
192+
ans += cnt
193+
a -= x
161194
}
162195
163-
ans := sign * tot
164-
if ans >= math.MinInt32 && ans <= math.MaxInt32 {
196+
if sign {
165197
return ans
166198
}
167-
return math.MaxInt32
199+
return -ans
168200
}
201+
```
169202

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;
175233
}
176234
```
177235

178-
### **C++**
236+
### **C#**
179237

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;
187243
}
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;
199246
}
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;
204260
}
205-
return INT32_MAX;
261+
return sign ? ans : -ans;
206262
}
207-
};
263+
}
208264
```
209265

210266
### **...**
Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
1-
class Solution {
2-
public:
3-
int divide(int a, int b) {
4-
int sign = 1;
5-
if (a < 0 ^ b < 0) {
6-
sign = -1;
7-
}
8-
9-
auto x = abs(static_cast<long long>(a));
10-
auto y = abs(static_cast<long long>(b));
11-
auto tot = 0ll;
12-
while (x >= y) {
13-
int cnt = 0;
14-
while (x >= (y << (cnt + 1))) {
15-
++cnt;
16-
}
17-
tot += 1ll << cnt;
18-
x -= y << cnt;
19-
}
20-
21-
auto ans = sign * tot;
22-
if (ans >= INT32_MIN && ans <= INT32_MAX) {
23-
return static_cast<int>(ans);
24-
}
25-
return INT32_MAX;
26-
}
27-
};
1+
class Solution {
2+
public:
3+
int divide(int a, int b) {
4+
if (b == 1) {
5+
return a;
6+
}
7+
if (a == INT_MIN && b == -1) {
8+
return INT_MAX;
9+
}
10+
bool sign = (a > 0 && b > 0) || (a < 0 && b < 0);
11+
a = a > 0 ? -a : a;
12+
b = b > 0 ? -b : b;
13+
int ans = 0;
14+
while (a <= b) {
15+
int x = b;
16+
int cnt = 1;
17+
while (x >= (INT_MIN >> 1) && a <= (x << 1)) {
18+
x <<= 1;
19+
cnt <<= 1;
20+
}
21+
ans += cnt;
22+
a -= x;
23+
}
24+
return sign ? ans : -ans;
25+
}
26+
};
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
public class Solution {
2+
public int Divide(int a, int b) {
3+
if (b == 1) {
4+
return a;
5+
}
6+
if (a == int.MinValue && b == -1) {
7+
return int.MaxValue;
8+
}
9+
bool sign = (a > 0 && b > 0) || (a < 0 && b < 0);
10+
a = a > 0 ? -a : a;
11+
b = b > 0 ? -b : b;
12+
int ans = 0;
13+
while (a <= b) {
14+
int x = b;
15+
int cnt = 1;
16+
while (x >= (int.MinValue >> 1) && a <= (x << 1)) {
17+
x <<= 1;
18+
cnt <<= 1;
19+
}
20+
ans += cnt;
21+
a -= x;
22+
}
23+
return sign ? ans : -ans;
24+
}
25+
}

0 commit comments

Comments
 (0)