|
116 | 116 | === "Go"
|
117 | 117 |
|
118 | 118 | ```go title="binary_search.go"
|
119 |
| - /* 二分查找(左闭右开) */ |
120 |
| - func binarySearch1(nums []int, target int) int { |
121 |
| - // 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1 |
122 |
| - i, j := 0, len(nums) |
123 |
| - // 循环,当搜索区间为空时跳出(当 i = j 时为空) |
124 |
| - for i < j { |
| 119 | + /* 二分查找(双闭区间) */ |
| 120 | + func binarySearch(nums []int, target int) int { |
| 121 | + // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素 |
| 122 | + i, j := 0, len(nums)-1 |
| 123 | + // 循环,当搜索区间为空时跳出(当 i > j 时为空) |
| 124 | + for i <= j { |
125 | 125 | m := (i + j) / 2 // 计算中点索引 m
|
126 |
| - if nums[m] < target { // 此情况说明 target 在区间 [m+1, j) 中 |
| 126 | + if nums[m] < target { // 此情况说明 target 在区间 [m+1, j] 中 |
127 | 127 | i = m + 1
|
128 |
| - } else if nums[m] > target { // 此情况说明 target 在区间 [i, m) 中 |
129 |
| - j = m |
| 128 | + } else if nums[m] > target { // 此情况说明 target 在区间 [i, m-1] 中 |
| 129 | + j = m - 1 |
130 | 130 | } else { // 找到目标元素,返回其索引
|
131 | 131 | return m
|
132 | 132 | }
|
|
161 | 161 | === "TypeScript"
|
162 | 162 |
|
163 | 163 | ```typescript title="binary_search.ts"
|
164 |
| - |
| 164 | + /* 二分查找(双闭区间) */ |
| 165 | + const binarySearch = function (nums: number[], target: number): number { |
| 166 | + // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素 |
| 167 | + let i = 0, j = nums.length - 1; |
| 168 | + // 循环,当搜索区间为空时跳出(当 i > j 时为空) |
| 169 | + while (i <= j) { |
| 170 | + const m = Math.floor(i + (j - i) / 2); // 计算中点索引 m |
| 171 | + if (nums[m] < target) { // 此情况说明 target 在区间 [m+1, j] 中 |
| 172 | + i = m + 1; |
| 173 | + } else if (nums[m] > target) { // 此情况说明 target 在区间 [i, m-1] 中 |
| 174 | + j = m - 1; |
| 175 | + } else { // 找到目标元素,返回其索引 |
| 176 | + return m; |
| 177 | + } |
| 178 | + } |
| 179 | + return -1; // 未找到目标元素,返回 -1 |
| 180 | + } |
165 | 181 | ```
|
166 | 182 |
|
167 | 183 | === "C"
|
|
208 | 224 | // 循环,当搜索区间为空时跳出(当 i = j 时为空)
|
209 | 225 | while (i < j) {
|
210 | 226 | int m = (i + j) / 2; // 计算中点索引 m
|
211 |
| - if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j) 中 |
| 227 | + if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j] 中 |
212 | 228 | i = m + 1;
|
213 |
| - else if (nums[m] > target) // 此情况说明 target 在区间 [i, m) 中 |
| 229 | + else if (nums[m] > target) // 此情况说明 target 在区间 [i, m] 中 |
214 | 230 | j = m;
|
215 | 231 | else // 找到目标元素,返回其索引
|
216 | 232 | return m;
|
|
230 | 246 | // 循环,当搜索区间为空时跳出(当 i = j 时为空)
|
231 | 247 | while (i < j) {
|
232 | 248 | int m = (i + j) / 2; // 计算中点索引 m
|
233 |
| - if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j) 中 |
| 249 | + if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j] 中 |
234 | 250 | i = m + 1;
|
235 |
| - else if (nums[m] > target) // 此情况说明 target 在区间 [i, m) 中 |
| 251 | + else if (nums[m] > target) // 此情况说明 target 在区间 [i, m] 中 |
236 | 252 | j = m;
|
237 | 253 | else // 找到目标元素,返回其索引
|
238 | 254 | return m;
|
|
252 | 268 | # 循环,当搜索区间为空时跳出(当 i = j 时为空)
|
253 | 269 | while i < j:
|
254 | 270 | m = (i + j) // 2 # 计算中点索引 m
|
255 |
| - if nums[m] < target: # 此情况说明 target 在区间 [m+1, j) 中 |
| 271 | + if nums[m] < target: # 此情况说明 target 在区间 [m+1, j] 中 |
256 | 272 | i = m + 1
|
257 |
| - elif nums[m] > target: # 此情况说明 target 在区间 [i, m) 中 |
| 273 | + elif nums[m] > target: # 此情况说明 target 在区间 [i, m] 中 |
258 | 274 | j = m
|
259 | 275 | else: # 找到目标元素,返回其索引
|
260 | 276 | return m
|
|
271 | 287 | // 循环,当搜索区间为空时跳出(当 i = j 时为空)
|
272 | 288 | for i < j {
|
273 | 289 | m := (i + j) / 2 // 计算中点索引 m
|
274 |
| - if nums[m] < target { // 此情况说明 target 在区间 [m+1, j) 中 |
| 290 | + if nums[m] < target { // 此情况说明 target 在区间 [m+1, j] 中 |
275 | 291 | i = m + 1
|
276 |
| - } else if nums[m] > target { // 此情况说明 target 在区间 [i, m) 中 |
| 292 | + } else if nums[m] > target { // 此情况说明 target 在区间 [i, m] 中 |
277 | 293 | j = m
|
278 | 294 | } else { // 找到目标元素,返回其索引
|
279 | 295 | return m
|
|
294 | 310 | // 循环,当搜索区间为空时跳出(当 i = j 时为空)
|
295 | 311 | while (i < j) {
|
296 | 312 | let m = parseInt((i + j) / 2); // 计算中点索引 m ,在 JS 中需使用 parseInt 函数取整
|
297 |
| - if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j) 中 |
| 313 | + if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j] 中 |
298 | 314 | i = m + 1;
|
299 |
| - else if (nums[m] > target) // 此情况说明 target 在区间 [i, m) 中 |
| 315 | + else if (nums[m] > target) // 此情况说明 target 在区间 [i, m] 中 |
300 | 316 | j = m;
|
301 | 317 | else // 找到目标元素,返回其索引
|
302 | 318 | return m;
|
|
309 | 325 | === "TypeScript"
|
310 | 326 |
|
311 | 327 | ```typescript title="binary_search.ts"
|
312 |
| - |
| 328 | + /* 二分查找(左闭右开) */ |
| 329 | + const binarySearch1 = function (nums: number[], target: number): number { |
| 330 | + // 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1 |
| 331 | + let i = 0, j = nums.length; |
| 332 | + // 循环,当搜索区间为空时跳出(当 i = j 时为空) |
| 333 | + while (i < j) { |
| 334 | + const m = Math.floor(i + (j - i) / 2); // 计算中点索引 m |
| 335 | + if (nums[m] < target) { // 此情况说明 target 在区间 [m+1, j] 中 |
| 336 | + i = m + 1; |
| 337 | + } else if (nums[m] > target) { // 此情况说明 target 在区间 [i, m] 中 |
| 338 | + j = m; |
| 339 | + } else { // 找到目标元素,返回其索引 |
| 340 | + return m; |
| 341 | + } |
| 342 | + } |
| 343 | + return -1; // 未找到目标元素,返回 -1 |
| 344 | + } |
313 | 345 | ```
|
314 | 346 |
|
315 | 347 | === "C"
|
|
330 | 362 | while (i < j)
|
331 | 363 | {
|
332 | 364 | int m = (i + j) / 2; // 计算中点索引 m
|
333 |
| - if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j) 中 |
| 365 | + if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j] 中 |
334 | 366 | i = m + 1;
|
335 |
| - else if (nums[m] > target) // 此情况说明 target 在区间 [i, m) 中 |
| 367 | + else if (nums[m] > target) // 此情况说明 target 在区间 [i, m] 中 |
336 | 368 | j = m;
|
337 | 369 | else // 找到目标元素,返回其索引
|
338 | 370 | return m;
|
|
407 | 439 | === "TypeScript"
|
408 | 440 |
|
409 | 441 | ```typescript title=""
|
410 |
| - |
| 442 | + // (i + j) 有可能超出 Number 的取值范围 |
| 443 | + let m = Math.floor((i + j) / 2); |
| 444 | + // 更换为此写法则不会越界 |
| 445 | + let m = Math.floor(i + (j - i) / 2); |
411 | 446 | ```
|
412 | 447 |
|
413 | 448 | === "C"
|
|
0 commit comments