|
| 1 | +/* |
| 2 | +* File: binary_search.ts |
| 3 | +* Created Time: 2022-12-27 |
| 4 | +* Author: Daniel (better.sunjian@gmail.com) |
| 5 | +*/ |
| 6 | + |
| 7 | +/* 二分查找(双闭区间) */ |
| 8 | +const binarySearch = function (nums: number[], target: number): number { |
| 9 | + // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素 |
| 10 | + let i = 0, j = nums.length - 1; |
| 11 | + // 循环,当搜索区间为空时跳出(当 i > j 时为空) |
| 12 | + while (i <= j) { |
| 13 | + let m = Math.floor(i + (j - i) / 2); // 计算中点索引 m |
| 14 | + if (nums[m] < target) { // 此情况说明 target 在区间 [m+1, j] 中 |
| 15 | + i = m + 1; |
| 16 | + } else if (nums[m] > target) { // 此情况说明 target 在区间 [i, m-1] 中 |
| 17 | + j = m - 1; |
| 18 | + } else { // 找到目标元素,返回其索引 |
| 19 | + return m; |
| 20 | + } |
| 21 | + } |
| 22 | + return -1; // 未找到目标元素,返回 -1 |
| 23 | +} |
| 24 | + |
| 25 | +/* 二分查找(左闭右开) */ |
| 26 | +const binarySearch1 = function (nums: number[], target: number): number { |
| 27 | + // 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1 |
| 28 | + let i = 0, j = nums.length; |
| 29 | + // 循环,当搜索区间为空时跳出(当 i = j 时为空) |
| 30 | + while (i < j) { |
| 31 | + const m = Math.floor(i + (j - i) / 2); // 计算中点索引 m |
| 32 | + if (nums[m] < target) { // 此情况说明 target 在区间 [m+1, j) 中 |
| 33 | + i = m + 1; |
| 34 | + } else if (nums[m] > target) { // 此情况说明 target 在区间 [i, m) 中 |
| 35 | + j = m; |
| 36 | + } else { // 找到目标元素,返回其索引 |
| 37 | + return m; |
| 38 | + } |
| 39 | + } |
| 40 | + return -1; // 未找到目标元素,返回 -1 |
| 41 | +} |
| 42 | + |
| 43 | + |
| 44 | +/* Driver Code */ |
| 45 | +const target = 6; |
| 46 | +const nums = [ 1, 3, 6, 8, 12, 15, 23, 67, 70, 92 ]; |
| 47 | + |
| 48 | +/* 二分查找(双闭区间) */ |
| 49 | +let index = binarySearch(nums, target); |
| 50 | +console.info('目标元素 6 的索引 = %d', index); |
| 51 | + |
| 52 | +/* 二分查找(左闭右开) */ |
| 53 | +index = binarySearch1(nums, target); |
| 54 | +console.info('目标元素 6 的索引 = %d', index); |
0 commit comments