📚 二分查找
在 42 亿个有序数据中用二分查找一个数据,最多需要比较 32 次。二分查找是一个时间复杂度为 O(logn) 的算法。logn 非常“恐怖”,即便 n 非常非常大,对应的 logn 也很小。
二分查找针对的是一个有序的数据集合,每次都通过跟区间的中间元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为 0。
💻 代码模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var 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; };
|
🏫 经典题目
主要包括这 3 类
- 简单的有序数组中查找元素
- 用于旋转后的、二维的有序数组
- 查找“近似值”问题
34.在排序数组中查找元素的第一个和最后一个位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| const binarySearch = (nums, target, lower) => { let left = 0, right = nums.length - 1, ans = nums.length; while (left <= right) { const mid = right + ((right - left) >> 1); if (nums[mid] > target || (lower && nums[mid] >= target)) { ans = mid; right = mid - 1; } else { left = mid + 1; } } return ans; };
const searchRange = (nums, target) => { let ans = [-1, -1]; const leftIdx = binarySearch(nums, target, true); const rightIdx = binarySearch(nums, target, false) - 1; if ( nums[leftIdx] === target && nums[rightIdx] === target && leftIdx >= 0 && rightIdx < nums.length ) { ans = [leftIdx, rightIdx]; } return ans; };
|