1.题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[
[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]
]
给定 target = 7,返回 true。
给定 target = 3,返回 false。
2.CODE
我的做法:从左上开始找,横向顺序查找,每次更新边界值n,避免多余的对比
评价:辣鸡代码,跟直接暴力搜索没啥区别,即使有个更新n的操作,也只是在一行对比中减少了一次比较
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
int i=0,j=0;
int m=array.size();
int n=array[0].size();
while(i<m && j<n){
while(target >= array[i][j] && j<n){
if(target == array[i][j])
return true;
j++;
}
n=j;
i++;
j=0;
}
return false;
}
};
3.正常做法
思路一:有序的查找首先想到二分查找,每行的查找都用二分查找即可(别忘了:二分查找的边界是i<=j,有等号的)
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
int i=0,j=0;
int m=array.size();
int n=array[0].size();
for(int i=0;i<m;i++){
int p=0,q=n-1;
while(p<=q){
int middle=(p+q)/2;
if(array[i][middle]>target)q=middle-1;
else if(array[i][middle]<target)p=middle+1;
else return true;
}
}
return false;
}
};
思路二:从左下开始查找,比他大的往右找,比他小的往左找(最优的思路,从右上查找亦可)
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
int m=array.size();
int n=array[0].size();
int i=m-1,j=0;
while(i>=0 && j<n){
if(array[i][j]>target)i--;
else if(array[i][j]<target)j++;
else return true;
}
return false;
}
};
4.总结:
1.看到有序查找,先反应是二分查找,注意边界是i<=j,有等号的,当i在j右侧时结束(快排,归并排序没等号)
2.横向纵向都有序,可以从左下,右上开始查找