模版:左闭右开[lo, hi)
伪码以下:算法
def binarySearch(lo, hi) { while (lo < hi) { int mid = (hi-lo)/2+lo; if (f(m)) return m // 这一步是optional的 if (g(m)) hi = mid; // 更新为[lo, mid) else lo = mid+1; // 更新为[mid-1, hi) } return lo or not found // 返回的lo是知足g(m)的最小index }
因此当咱们要在一个有序的区间内寻找到第一个知足条件的数的时候,能够用binary search来查找。
如162题Find Peak Element这一题,须要咱们找到一个局部峰值,题目要求的时间复杂度是logN,因此就想到能够用binary search来作,可是binary search怎么写一开始是没有思路的,比较nums[mid]和nums[mid-1],mums[mid+1]的大小吗?若是mums[mid] > mums[mid-1]该怎么搜索呢?数组
可是这一题咱们会用O(N)的算法把数组扫描一遍获得峰值(这种方法我也没想出来,我一直在考虑和两边的值比较,但其实只要比较一边的大小就能够了)。也就是咱们找到第一个符合nums[i] > nums[i+1]的i,就是咱们要找的第一个峰值的index。代码以下:code
class Solution { public int findPeakElement(int[] nums) { for(int i = 0; i < nums.length-1; i ++) { if (nums[i] > nums[i+1]) return i; } return nums.length-1; } }
看到这里就能当即联想到能够用binary search改写这段代码,代码以下:get
class Solution { public int findPeakElement(int[] nums) { int lo = 0, hi = nums.length-1; while (lo < hi) { int mid = (hi-lo)/2+lo; if (nums[mid] > nums[mid+1]) hi = mid; else lo = mid+1; } return lo; } }
再看一道很是基础的题目3五、Find Insert Position,在一个sorted array中寻找某个数,若是这个数存在就返回它的index,若是不存在则返回它应该插入的位置。本质是一道求lower_bound的问题,也就是找到第一个使得nums[i] >= target的i,代码以下:it
class Solution { public int searchInsert(int[] nums, int target) { int lo = 0, hi = nums.length; while (lo < hi) { int mid = (hi-lo)/2+lo; if (nums[mid] >= target) hi = mid; else lo = mid+1; } return lo; } }
34题Find First and Last Position。在一个存在重复元素的sorted array里,给定一个target,找到target第一次出现的位置和最后一次出现的位置,若是不存在则返回-1。第一次出现的位置:求lowerbound,最后一次出现的位置:upperbound-1。代码以下:io
class Solution { public int[] searchRange(int[] nums, int target) { int[] res = new int[2]; Arrays.fill(res, -1); if (nums == null || nums.length == 0) return res; int lo = 0, hi = nums.length; while (lo < hi) { int mid = (hi-lo)/2+lo; if (target <= nums[mid]) hi = mid; else lo = mid+1; } if (lo == nums.length || nums[lo] != target) return res; res[0] = lo; hi = nums.length; while (lo < hi) { int mid = (hi-lo)/2+lo; if (target < nums[mid]) hi = mid; else lo = mid+1; } res[1] = lo-1; return res; } }