基本的二分搜索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| let binarySearch = function (nums, target) { let left = 0; let right = nums.length - 1;
while (left <= right) { let mid = left + ((right - left) >> 1);
if (nums[mid] == target) { return mid; } else if (nums[mid] < target) { left = mid + 1; } else { right = mid - 1; } }
return -1; };
|
因为我们是要查找一个数存不存在,所以当 left == right 时,我们也应该继续执行 while 查找。
寻找左侧边界的二分搜索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| let searchLeftBound = function (nums, target) { if (nums.length == 0) return -1; let left = 0; let right = nums.length;
while (left < right) { let mid = left + ((right - left) >> 1);
if (nums[mid] == target) { right = mid; } else if (nums[mid] > target) { right = mid; } else if (nums[mid] < target) { left = mid + 1; } }
return nums[left] == target ? left : -1; };
|
对于 nums = [1, 2, 2, 2, 3] 和 target = 2 而言,left 的结果为 1,可以理解为 nums 中小于 2 的个数有 1 个。
当 target 大于 nums 所有数时,left 的结果为 nums.length;此时 nums[left] 即 nums[nums.length] 为 undefined,必然不等于 target。
寻找右侧边界的二分搜索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| let searchRightBound = function (nums, target) { let left = 0; let right = nums.length - 1;
while (left <= right) { let mid = left + ((right - left) >> 1);
if (nums[mid] == target) { left = mid + 1; } else if (nums[mid] > target) { right = mid - 1; } else if (nums[mid] < target) { left = mid + 1; } }
if (right < 0 || nums[right] != target) return -1;
return right; };
|
当 nums 为非递减顺序时,right < 0 表示 target 比所有元素都小,即算法不断在执行 right = mid - 1;