Skip to content

Commit f55fa10

Browse files
committed
feat: update solution to lc problem: No.0029
No.0029.Divide Two Integers
1 parent bd9d5bc commit f55fa10

File tree

3 files changed

+65
-72
lines changed

3 files changed

+65
-72
lines changed

solution/0000-0099/0029.Divide Two Integers/README.md

+25-32
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,13 @@
4040

4141
<!-- 这里可写通用的实现逻辑 -->
4242

43-
通过下面这段伪代码,不难理解除法本质上就是减法,但是一次循环只能做一次减法,效率太低会导致超时,所以再加上快速幂的思想优化即可
44-
45-
```py
46-
sign = -1 if a * b < 0 else 1
47-
a = abs(a)
48-
b = abs(b)
49-
cnt = 0
50-
while a >= b:
51-
a -= b
52-
cnt += 1
53-
return sign * cnt
54-
```
43+
**方法一:模拟 + 快速幂**
44+
45+
除法本质上就是减法,题目要求我们计算出两个数相除之后的取整结果,其实就是计算被除数是多少个除数加上一个小于除数的数构成的。但是一次循环只能做一次减法,效率太低会导致超时,可借助快速幂的思想进行优化。
46+
47+
需要注意的是,由于题目明确要求最大只能使用 32 位有符号整数,所以需要将除数和被除数同时转换为负数进行计算。因为转换正数可能会导致溢出,如当被除数为 `INT32_MIN` 时,转换为正数时会大于 `INT32_MAX`
48+
49+
假设被除数为 `a`,除数为 `b`,则时间复杂度为 $O(\log a \times \log b)$,空间复杂度 $O(1)$。
5550

5651
<!-- tabs:start -->
5752

@@ -112,36 +107,34 @@ class Solution {
112107

113108
```go
114109
func divide(a int, b int) int {
115-
sign := 1
116-
if a*b < 0 {
117-
sign = -1
110+
sign, ans, INT32_MAX, INT32_MIN, LIMIT := false, 0, 1<<31-1, -1<<31, -1<<31/2
111+
if (a > 0 && b < 0) || (a < 0 && b > 0) {
112+
sign = true
118113
}
119-
120-
a = abs(a)
121-
b = abs(b)
122-
123-
tot := 0
124-
for a >= b {
114+
a, b = convert(a), convert(b)
115+
for a <= b {
125116
cnt := 0
126-
for a >= (b << (cnt + 1)) {
117+
// (b<<cnt) >= LIMIT 是为了避免 b<<(cnt+1) 发生溢出
118+
for (b<<cnt) >= LIMIT && a <= (b<<(cnt+1)) {
127119
cnt++
128120
}
129-
tot += 1 << cnt
130-
a -= b << cnt
121+
ans = ans + -1<<cnt
122+
a = a - b<<cnt
131123
}
132-
133-
ans := sign * tot
134-
if ans >= math.MinInt32 && ans <= math.MaxInt32 {
124+
if sign {
135125
return ans
136126
}
137-
return math.MaxInt32
127+
if ans == INT32_MIN {
128+
return INT32_MAX
129+
}
130+
return -ans
138131
}
139132

140-
func abs(a int) int {
141-
if a < 0 {
142-
return -a
133+
func convert(v int) int {
134+
if v > 0 {
135+
return -v
143136
}
144-
return a
137+
return v
145138
}
146139
```
147140

solution/0000-0099/0029.Divide Two Integers/README_EN.md

+22-20
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939

4040
## Solutions
4141

42+
**Approach 1: Quick Power**
43+
44+
Time complexity $O(\log a \times \log b)$, Space complexity $O(1)$.
45+
4246
<!-- tabs:start -->
4347

4448
### **Python3**
@@ -94,36 +98,34 @@ class Solution {
9498

9599
```go
96100
func divide(a int, b int) int {
97-
sign := 1
98-
if a*b < 0 {
99-
sign = -1
101+
sign, ans, INT32_MAX, INT32_MIN, LIMIT := false, 0, 1<<31-1, -1<<31, -1<<31/2
102+
if (a > 0 && b < 0) || (a < 0 && b > 0) {
103+
sign = true
100104
}
101-
102-
a = abs(a)
103-
b = abs(b)
104-
105-
tot := 0
106-
for a >= b {
105+
a, b = convert(a), convert(b)
106+
for a <= b {
107107
cnt := 0
108-
for a >= (b << (cnt + 1)) {
108+
// (b<<cnt) >= LIMIT 是为了避免 b<<(cnt+1) 发生溢出
109+
for (b<<cnt) >= LIMIT && a <= (b<<(cnt+1)) {
109110
cnt++
110111
}
111-
tot += 1 << cnt
112-
a -= b << cnt
112+
ans = ans + -1<<cnt
113+
a = a - b<<cnt
113114
}
114-
115-
ans := sign * tot
116-
if ans >= math.MinInt32 && ans <= math.MaxInt32 {
115+
if sign {
117116
return ans
118117
}
119-
return math.MaxInt32
118+
if ans == INT32_MIN {
119+
return INT32_MAX
120+
}
121+
return -ans
120122
}
121123

122-
func abs(a int) int {
123-
if a < 0 {
124-
return -a
124+
func convert(v int) int {
125+
if v > 0 {
126+
return -v
125127
}
126-
return a
128+
return v
127129
}
128130
```
129131

Original file line numberDiff line numberDiff line change
@@ -1,32 +1,30 @@
11
func divide(a int, b int) int {
2-
sign := 1
3-
if a*b < 0 {
4-
sign = -1
2+
sign, ans, INT32_MAX, INT32_MIN, LIMIT := false, 0, 1<<31-1, -1<<31, -1<<31/2
3+
if (a > 0 && b < 0) || (a < 0 && b > 0) {
4+
sign = true
55
}
6-
7-
a = abs(a)
8-
b = abs(b)
9-
10-
tot := 0
11-
for a >= b {
6+
a, b = convert(a), convert(b)
7+
for a <= b {
128
cnt := 0
13-
for a >= (b << (cnt + 1)) {
9+
// (b<<cnt) >= LIMIT 是为了避免 b<<(cnt+1) 发生溢出
10+
for (b<<cnt) >= LIMIT && a <= (b<<(cnt+1)) {
1411
cnt++
1512
}
16-
tot += 1 << cnt
17-
a -= b << cnt
13+
ans = ans + -1<<cnt
14+
a = a - b<<cnt
1815
}
19-
20-
ans := sign * tot
21-
if ans >= math.MinInt32 && ans <= math.MaxInt32 {
16+
if sign {
2217
return ans
2318
}
24-
return math.MaxInt32
19+
if ans == INT32_MIN {
20+
return INT32_MAX
21+
}
22+
return -ans
2523
}
2624

27-
func abs(a int) int {
28-
if a < 0 {
29-
return -a
25+
func convert(v int) int {
26+
if v > 0 {
27+
return -v
3028
}
31-
return a
29+
return v
3230
}

0 commit comments

Comments
 (0)