硅基俊宁.
Skills · 技能体系 ↗
← 返回文章

二分查找与左右边界

俊宁 · 日期未详
整理自原官网的历史学习笔记,保留原有译文、引用和署名,不把资料内容认作本人研究或实践成果。本篇有格式适配或明确勘误,详见官网迁移清单。
查看官网迁移清单
二分查找与左右边界封面

二分搜索算法

什么是二分搜索

二分搜索(Binary Search)是一种针对有序数组的高效查找算法。其核心思想是:

前提条件

算法思路

  1. 初始化左右指针 left=0 和 right=arr.length-1。
  2. 循环计算中间索引值 mid=left + Math.floor((right - left) / 2)
  3. 比较中间元素与目标值:
  1. 若循环结束未找到,返回 -1。

Javascript 实现

function binarySearch(arr, target) {
  let left = 0;
  let right = arr.length - 1;
  while (left <= right) {
    const mid = left + Math.floor((right - left) / 2); // 取区间中点并向下取整
    if (arr[mid] === target) {
      return mid; // 找到目标
    } else if (arr[mid] < target) {
      left = mid + 1; // 搜索右半区
    } else {
      right = mid - 1; // 搜索左半区
    }
  }
  return -1; // 未找到
}

const a = [1, 2, 3, 4, 6, 7]
binarySearch(a, 1)

关键点:

单元测试

describe('二分搜索算法测试', () => {
  const sortedArr = [2, 5, 8, 12, 16, 23, 38, 56];

  it('目标存在时返回正确索引', () => {
    expect(binarySearch(sortedArr, 23)).toBe(5); // 中间位置
  });

  it('目标不存在时返回-1', () => {
    expect(binarySearch(sortedArr, 10)).toBe(-1); // 不存在元素
  });

  it('目标在数组开头', () => {
    expect(binarySearch(sortedArr, 2)).toBe(0); // 边界测试
  });

  it('目标在数组末尾', () => {
    expect(binarySearch(sortedArr, 56)).toBe(7); // 边界测试
  });

  it('空数组返回-1', () => {
    expect(binarySearch([], 5)).toBe(-1); // 异常输入测试
  });
});

测试原则:

变体:查找左右边界

左边界​(第一个匹配元素)

function lowerBound(arr, target) {
  let left = 0, right = arr.length;
  while (left < right) {
    const mid = left + Math.floor((right - left) / 2);
    arr[mid] < target ? (left = mid + 1) : (right = mid);
  }
  return arr[left] === target ? left : -1;
}

​右边界​(最后一个匹配元素)

function upperBound(arr, target) {
  let left = 0, right = arr.length;
  while (left < right) {
    const mid = left + Math.floor((right - left) / 2);
    arr[mid] <= target ? (left = mid + 1) : (right = mid);
  }
  return arr[left - 1] === target ? left - 1 : -1;
}

力扣真题

通过以上实现与测试,你可以掌握二分搜索的核心逻辑,并应对不同场景的需求。建议结合 LeetCode 题目(如 #34 查找边界 和 #704 标准二分)进一步练习。