Skip to content

Commit 32a95d3

Browse files
committed
二分: 位移实现除法
Change-Id: I7dc4d16f23096fbd5bc08e869448fdc69dab03f4
1 parent ffa3f46 commit 32a95d3

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

go/leetcode/29.两数相除.go

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* @lc app=leetcode.cn id=29 lang=golang
3+
*
4+
* [29] 两数相除
5+
*
6+
* https://leetcode-cn.com/problems/divide-two-integers/description/
7+
*
8+
* algorithms
9+
* Medium (18.27%)
10+
* Likes: 128
11+
* Dislikes: 0
12+
* Total Accepted: 13.2K
13+
* Total Submissions: 72.2K
14+
* Testcase Example: '10\n3'
15+
*
16+
* 给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
17+
*
18+
* 返回被除数 dividend 除以除数 divisor 得到的商。
19+
*
20+
* 示例 1:
21+
*
22+
* 输入: dividend = 10, divisor = 3
23+
* 输出: 3
24+
*
25+
* 示例 2:
26+
*
27+
* 输入: dividend = 7, divisor = -3
28+
* 输出: -2
29+
*
30+
* 说明:
31+
*
32+
*
33+
* 被除数和除数均为 32 位有符号整数。
34+
* 除数不为 0。
35+
* 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−2^31,  2^31 − 1]。本题中,如果除法结果溢出,则返回 2^31 − 1。
36+
*
37+
*
38+
*/
39+
40+
// 最简单的方式是不断减被除数,可减的次数就是商;可以用位移来将被除数乘2,从而加速运算
41+
func divide(dividend int, divisor int) int {
42+
int_max := 1<<31 - 1 // 2147483647
43+
int_min := ^int_max // -2147483648
44+
if divisor == 0 {
45+
return int_max
46+
}
47+
48+
flag := -1
49+
if (dividend < 0 && divisor < 0) || (dividend > 0 && divisor > 0) {
50+
flag = 1
51+
}
52+
if dividend < 0 {
53+
dividend = -dividend
54+
}
55+
if divisor < 0 {
56+
divisor = -divisor
57+
}
58+
s := uint64(dividend)
59+
p := uint64(divisor)
60+
i := 1
61+
ret := 0
62+
for s >= p {
63+
tmp := p << 1 // *2
64+
if s > tmp { // 10 6
65+
p = tmp // 6
66+
i *= 2 // 2
67+
} else { // 10 12
68+
ret += i // 2, 3
69+
s -= p // 10 - 6 = 4 - 3 = 1
70+
p = uint64(divisor) // 3
71+
i = 1
72+
}
73+
}
74+
ret = flag*ret
75+
if ret > int_max {
76+
return int_max
77+
}
78+
if ret < int_min {
79+
return int_max
80+
}
81+
return ret
82+
}
83+

0 commit comments

Comments
 (0)