41
41
42
42
<!-- 这里可写通用的实现逻辑 -->
43
43
44
- 二分查找。
44
+ ** 方法一:二分查找**
45
+
46
+ 我们定义二分查找的左边界 $l = 0$,右边界 $r = x$,然后在 $[ l, r] $ 范围内查找平方根。
47
+
48
+ 在每一步查找中,我们找出中间值 $mid = (l + r + 1) / 2$,如果 $mid > x / mid$,说明平方根在 $[ l, mid - 1] $ 范围内,我们令 $r = mid - 1$;否则说明平方根在 $[ mid, r] $ 范围内,我们令 $l = mid$。
49
+
50
+ 查找结束后,返回 $l$ 即可。
51
+
52
+ 时间复杂度 $O(\log x)$,空间复杂度 $O(1)$。
45
53
46
54
<!-- tabs:start -->
47
55
52
60
``` python
53
61
class Solution :
54
62
def mySqrt (self , x : int ) -> int :
55
- left, right = 0 , x
56
- while left < right:
57
- mid = (left + right + 1 ) >> 1
58
- # mid*mid <= x
59
- if mid <= x // mid:
60
- left = mid
63
+ l, r = 0 , x
64
+ while l < r:
65
+ mid = (l + r + 1 ) >> 1
66
+ if mid > x // mid:
67
+ r = mid - 1
61
68
else :
62
- right = mid - 1
63
- return left
69
+ l = mid
70
+ return l
64
71
```
65
72
66
73
### ** Java**
@@ -70,17 +77,16 @@ class Solution:
70
77
``` java
71
78
class Solution {
72
79
public int mySqrt (int x ) {
73
- int left = 0 , right = x;
74
- while (left < right) {
75
- int mid = (left + right + 1 ) >>> 1 ;
76
- if (mid <= x / mid) {
77
- // mid*mid <= x
78
- left = mid;
80
+ int l = 0 , r = x;
81
+ while (l < r) {
82
+ int mid = (l + r + 1 ) >>> 1 ;
83
+ if (mid > x / mid) {
84
+ r = mid - 1 ;
79
85
} else {
80
- right = mid - 1 ;
86
+ l = mid;
81
87
}
82
88
}
83
- return left ;
89
+ return l ;
84
90
}
85
91
}
86
92
```
@@ -91,15 +97,16 @@ class Solution {
91
97
class Solution {
92
98
public:
93
99
int mySqrt(int x) {
94
- long long left = 0, right = x;
95
- while (left < right) {
96
- long long mid = left + ((right - left + 1) >> 1);
97
- if (mid <= x / mid)
98
- left = mid;
99
- else
100
- right = mid - 1;
100
+ int l = 0, r = x;
101
+ while (l < r) {
102
+ int mid = (l + r + 1ll) >> 1;
103
+ if (mid > x / mid) {
104
+ r = mid - 1;
105
+ } else {
106
+ l = mid;
107
+ }
101
108
}
102
- return (int) left ;
109
+ return l ;
103
110
}
104
111
};
105
112
```
@@ -108,16 +115,7 @@ public:
108
115
109
116
```go
110
117
func mySqrt(x int) int {
111
- left, right := 0, x
112
- for left < right {
113
- mid := left + (right-left+1)>>1
114
- if mid <= x/mid {
115
- left = mid
116
- } else {
117
- right = mid - 1
118
- }
119
- }
120
- return left
118
+ return sort.Search(x+1, func(i int) bool { return i*i > x }) - 1
121
119
}
122
120
```
123
121
@@ -129,17 +127,16 @@ func mySqrt(x int) int {
129
127
* @return {number}
130
128
*/
131
129
var mySqrt = function (x ) {
132
- let left = 0 ;
133
- let right = x;
134
- while (left < right) {
135
- const mid = (left + right + 1 ) >>> 1 ;
136
- if (mid <= x / mid) {
137
- left = mid;
130
+ let [l, r] = [0 , x];
131
+ while (l < r) {
132
+ const mid = (l + r + 1 ) >> 1 ;
133
+ if (mid > x / mid) {
134
+ r = mid - 1 ;
138
135
} else {
139
- right = mid - 1 ;
136
+ l = mid;
140
137
}
141
138
}
142
- return left ;
139
+ return l ;
143
140
};
144
141
```
145
142
@@ -148,20 +145,16 @@ var mySqrt = function (x) {
148
145
``` cs
149
146
public class Solution {
150
147
public int MySqrt (int x ) {
151
- int left = 0 , right = x ;
152
- while (left < right )
153
- {
154
- int mid = left + right + 1 >> 1 ;
155
- if (mid <= x / mid )
156
- {
157
- left = mid ;
158
- }
159
- else
160
- {
161
- right = mid - 1 ;
148
+ int l = 0 , r = x ;
149
+ while (l < r ) {
150
+ int mid = (l + r + 1 ) >>> 1 ;
151
+ if (mid > x / mid ) {
152
+ r = mid - 1 ;
153
+ } else {
154
+ l = mid ;
162
155
}
163
156
}
164
- return left ;
157
+ return l ;
165
158
}
166
159
}
167
160
```
@@ -171,19 +164,19 @@ public class Solution {
171
164
``` rust
172
165
impl Solution {
173
166
pub fn my_sqrt (x : i32 ) -> i32 {
174
- if x < 2 {
175
- return x ;
176
- }
177
- let mut l = 1 ;
178
- let mut r = x / 2 ;
167
+ let mut l = 0 ;
168
+ let mut r = x ;
169
+
179
170
while l < r {
180
- let mid = (l + r + 1 ) >> 1 ;
181
- if x / mid < mid {
171
+ let mid = (l + r + 1 ) / 2 ;
172
+
173
+ if mid > x / mid {
182
174
r = mid - 1 ;
183
175
} else {
184
176
l = mid ;
185
177
}
186
178
}
179
+
187
180
l
188
181
}
189
182
}
0 commit comments