二分查找/折半查找
前提
数列有序;
数列使用顺序存储结构
过程
将目标元素与有序数列的中间元素比较大小, 比中间元素大, 则在数列的右半部分查找, 比中间元素小, 则在数列的左半部分查找, 如果相等, 则找到.
不会查找所有的元素, 查找的数据量正好符合元素的对数, 正常情况每次查找的元素都在对半减少.所以时间复杂度为 $O(log_2N)$.

优化
根据要找的key的大小, 从更接近的位置进行查找.eg.1-100000找10, 肯定采取顺序查找而不是折半查找.
called 插值查找. 适用于数列比较大&均匀的数列.
使用场景
有序; 元素个数较多; 不进行频繁增删
代码实现
普通的二分查找
1 | // 标准的二分查找模板 |
寻找左侧边界的二分查找(模板)
1 | var search_left = (nums, target) => { |
寻找右侧边界的二分查找(模板)
1 | var search_right = (nums, target) => { |
[33] Search in Rotated Sorted Array
You are given an integer array
numssorted in ascending order, and an integertarget.Suppose that
numsis rotated at some pivot unknown to you beforehand (i.e.,[0,1,2,4,5,6,7]might become[4,5,6,7,0,1,2]).If
targetis found in the array return its index, otherwise, return-1.
- 确定有序部分 判断target在哪个部分
- 边界 当数组两端或者中间找不到target时的情况处理
1 | // 比较中间元素与最后一个元素的大小 确定有序区间 |
[35] Search Insert Position
Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
You may assume no duplicates in the array.
My solution
我是哪里来的if-else怪物(为了边界情况, 疯狂if-else), 代码一点都不优雅, 考点应该是折半查找, 被我写成这个样子. 不说了, 我去找优雅解法去了…..
1 | var searchInsert = function (nums, target) { |
solution on the Internet
参考网上的解法, 优化了一下, 感觉稍微简洁了些, 这里的mid取值是靠左的.所以一开始判断end值
1 | var searchInsert = function (nums, target) { |
[81] Search in Rotated Sorted Array II
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e.,
[0,0,1,2,2,5,6]might become[2,5,6,0,0,1,2]).You are given a target value to search. If found in the array return
true, otherwise returnfalse.Follow up:
- This is a follow up problem to Search in Rotated Sorted Array, where
numsmay contain duplicates.- Would this affect the run-time complexity? How and why?
有重复元素的有序数组分为了两个部分, 颠倒之后的数组的第一个元素一定>=第二部分的任意元素.
将需要搜索的部分分为三个部分, 前半个数组[left, mid)/中间元素mid/后半个数组(mid, right]
mid和target可能分别在左右部分, 对这两者的位置组合进行分情况讨论. 如果target在左min(left)和max(right)之间, 则直接返回false.
1 | // 原来没有重复元素时 判断有序数组比较好判断 直接比较大小 |
[153] Find Minimum in Rotated Sorted Array
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e.,
[0,1,2,4,5,6,7]might become[4,5,6,7,0,1,2]).Find the minimum element.
You may assume no duplicate exists in the array.
总体思路: 使用二分查找, 不断寻找有序部分的最小值, 返回最小值中的最小值.
时间复杂度: logN
1 | // 首先确定有序的部分 保留其最小值x |