题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
1、二分查找的过程中,会产生一棵二叉判定树,二叉判定树的特点就是,左子树小于根节点,右子树大于根节点。利用这个性质,我们可以将二维数组模拟成一个二叉判定树,此时就需要找出根节点,使得左子树小于根节点,右子树大于根节点,并且它的孩子节点也符合这种特性。
利用二维数组由上到下,由左到右递增的规律,那么选取右上角或者左下角的元素a[row][col]与target进行比较,
当target小于元素a[row][col]时,那么target必定在元素a所在行的左边,即col--;
当target大于元素a[row][col]时,那么target必定在元素a所在列的下边,即row++;
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
int row,col,m,n;
m=array.size(); //求数组的行数
n=array[0].size(); //求数组的列数
row=0,col=n-1; //右上角数的坐标
bool flag=false; //定义一个标志量,用于记录是否找到,初始化为false
while(!flag && row<m && col> -1) {
if(array[row][col]>target) { //比目标数大,往左查找,列数减一
col--;
} else if(array[row][col]<target){ //比目标数小,往下查找,行数加一
row++;
} else {
flag=true;
break;
}
}
if(flag){
return true;
} else {
return false;
}
}
};
2、利用二分查找,即对每一行进行二分查找。这种方法可以解决当你的数组并不是矩阵的情形,即每一行的数字不一样多 O(nlogn) 运行时间比前一种方法长。
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
int row,col,m,n;
m=array.size(); //求数组的行数
for(row=0;row<m;row++) {
int low=0;
int high=array[row].size(); //求对应行的列数
while(low<=high) {
int mid=(low+high)/2; //第row行的 中间数
if(array[row][mid]<target){
low=mid+1; //中间数比目标数小,则在右边
} else if(array[row][mid]>target){
high=mid-1; //中间数比目标数大,则在左边
} else {
return true;
}
}
}
return false;
}
};
3、整个矩阵二分法,即利用对角线将矩阵分成上三角和下三角矩阵。再分别对两个三角矩阵进行二分查找.
class Solution {
public:
bool Find(int target, vector<vector<int> > array){
if( array.size() == 0 || array[0].size() == 0){ //当矩阵不符合条件时,返回false
return false;
}
int low,high,mid;
for(int j = 0; j < array.size(); j++){ //判断左下角的数
low = j;
high = array.size() - 1;
mid = (low + high) / 2;
while(low <= high){
if(array[mid][j] == target){
return true;
}
if(array[mid][j] > target){
high = mid - 1;
}else{
low = mid + 1;
}
mid = (low + high) / 2;
}
}
for(int i = 0; i < array.size() - 1; i++){ //判断右上角的数,i为列数
low = i + 1;
high = array[i].size() -1;
mid = (low + high) / 2;
while(low <= high){
if(array[i][mid] == target){
return true;
}
if(array[i][mid] > target){
high = mid - 1;
}else{
low = mid + 1;
}
mid = (low + high) / 2;
}
}
return false;
}
};