需要注意的是:
1、二分法查找是在有序的基础上
2、确定判断是否找到的条件,确定判断函数
3、边界条件控制
1)闭区间[a,b]
2)半开半闭区间[a,b)
例题:
1、首个失败的产品。 这是一个闭区间的例子。
假设有一系列产品[1,2,3,4,5,6,7...],现在发现最新的产品是损坏的,你需要找出第一个失败了的产品,也就是出问题的那个产品。是否出问题通过函数isBadVersion(version)来判断。
分析:
1 int left =1; 2 int right =n;//n是数组长度 3 4 //循环区域 5 while(left<=right){//缺乏等号会差一步 6 //取中间值 7 int middle = left + (right-left)/2; //直接(left+right)/2有溢出的可能 8 if(isBadVersion(middle)){ //如果是badVersion 9 right = middle -1; //右边界向左 10 }else{ //不是badVersion 11 left = middle +1; //左边界向右 12 } 13 return left; 14 15 }
闭区间循环终止条件是left>right,目标值在left
至于开区间,那就直接往闭区间这种套吧。
最后写一个二分查找的变形。
题目:在一个m*n的矩阵中,查询是否存在数字x。矩阵有两个特性:1、每行数字从小到大排序 2、上一行第一个数小于下一行第一个数
例子:
有矩阵
[
[1,3,5,7],
[9,13,18,23],
[33,45,56,78]
]
给定数字18,返回true
一种解法:
1 public boolean searchMatrix(int[][] a,int target){ 2 //确定边界条件 3 if(a==null ||a.length==0)return false; 4 5 6 //m是行数,n是列数 7 int m = a.length,n=matrix[0].length; 8 //用来控制循环里的行和列 9 int i=m-1,j=0; 10 11 while(i>=0 && j<n){ 12 if(matrix[i][j]<target)j++; 13 else if(matrix[i][j])>target) i--; 14 else return true; 15 } 16 return false; 17 18 }