二分查找,一款我的薄弱点,每次都会写成死循环。对二分查找比较迷惑的话可以看这个↓
用的方法比较复杂(对比事后看的答案)
想法是先搜索行,用二分法,给定上界b和下界a,取i是两者中间数,若第i行最后一项比target大则对比第i行第一项和target,若比target小则选定这一行,若大则b=i;若第i行最后一项比target小则a=i……如此循环直到a==b,找出target理论位置在哪一行。
(这里可以直接使用函数upper_bound,看了答案才知道这么一个函数模板是upper_bound( arr[],arr[]+size,num),返回是大于等于num的数的地址)
然后在这一行中继续二分寻找target,继续自己写二分,依旧是定上界b下界a,j是二者中间数,对比第j项和target,如果等于则直接返回true,不然就一直循环到上界等于下界,最后return false。
(这里可以用函数binary_reserch,也是看了答案才知道这么一个函数,模板是binary_search(arr[],arr[]+size,indx),查找在arr[]中index是否存在,返回是bool类型)
ps:补充一下这样做需要首先检测target是否比第一行第一个数字小或比最后一行最后一个数字大,如果这样的话直接返回false。
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int n=matrix.size();
int m=matrix[0].size();
int a=0;
int b=n-1;
int i=n/2;
if(target>matrix[n-1][m-1]||target<matrix[0][0]) return 0;
while(a!=b){
if(matrix[i][m-1]>=target){
if(matrix[i][0]<=target){
a=i;b=i;
}
else b=i;
}
else a=i+1;
i=(a+b)/2;
}
a=0;b=m-1;
int j=m/2;
if(matrix[i][j]==target) return 1;
while(a!=b){
if(matrix[i][j]>target) b=j;
else if(matrix[i][j]<target) a=j+1;
j=(a+b)/2;
if(matrix[i][j]==target) return 1;
}
return 0;
}
};
最后写出来是这么一大串东西,答案直接用了俩函数,比这个短多了。
答案还有一种方法,是我想到了但止步于想象的,就是将矩阵的邻接行直接拼接起来,然后直接用二分找这个拼接后的数组中有没有target,有兴趣可以尝试。