二分查找(Binary Search)是一种常用的搜索算法,用于在有序数组中快速查找目标值。以下是二分查找的详细理论知识、优缺点以及适用场景:
-
理论知识:
- 基本原理:二分查找通过比较目标值与数组的中间元素,将查找范围缩小一半,直到找到目标值或查找范围为空。
- 前提条件:二分查找要求数组必须是有序的,可以是升序或降序。
- 过程步骤:
- 初始化左右指针,分别指向数组的第一个和最后一个元素;
- 计算中间元素的索引;
- 比较目标值与中间元素的大小,根据比较结果调整左右指针;
- 重复上述过程直到找到目标值或查找范围为空。
-
优点:
- 效率高:二分查找的时间复杂度为O(log n),相较于线性查找的O(n),性能更好。
- 算法简单:二分查找的实现逻辑清晰,易于理解和实现。
- 适用于有序数组:只有在有序数组中才能应用二分查找,如果数组无序,则需要先进行排序。
-
缺点:
- 仅适用于有序数组:二分查找要求目标数组是有序的,如果数组无序,则无法应用二分查找。
- 需要额外空间:二分查找通常需要额外的指针来指示查找范围,使得空间复杂度较高。
- 数据更新困难:如果目标数组需要频繁更新,如插入、删除等操作,需要重复进行排序,降低效率。
-
适用场景:
- 针对有序数组:二分查找适用于对有序数组进行快速查找,可以有效地减少查找时间。
- 大规模数据查找:对于大规模数据集合,二分查找能够迅速缩小查找范围,提高查找效率。
- 需要高效查找的场景:在对数据要求较高且需要快速查找的场景中,二分查找是一个好的选择。
以上是关于二分查找的详细理论知识、优缺点以及适用场景。希望对你有帮助!
接下来来到简简单单的小例题:
704. 二分查找
给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。
示例 1:
输入:nums
= [-1,0,3,5,9,12],target
= 9 输出: 4 解释: 9 出现在nums
中并且下标为 4
示例 2:
输入:nums
= [-1,0,3,5,9,12],target
= 2 输出: -1 解释: 2 不存在nums
中因此返回 -1
// 在有序数组中搜索目标值并返回其索引
public int search(int[] nums, int target) {int l = 0; // 左边界int r = nums.length; // 右边界,注意这里是数组长度,不是最后一个元素的索引while (l <= r) { // 当左边界小于等于右边界时执行循环int mid = (l + r) / 2; // 计算中间位置if (target == nums[mid]) { // 如果目标值等于中间值,返回中间索引return mid;}if (target < nums[mid]) { // 如果目标值小于中间值,缩小右边界r = mid - 1;}if (target > nums[mid]) { // 如果目标值大于中间值,增大左边界l = mid + 1;}}return -1; // 未找到目标值,返回-1
}