Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ba7bb98

Browse files
feat: add solutions to lc/lcof2 problems (#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)

AltStyle によって変換されたページ (->オリジナル) /