题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
绝望的思路
想到使用二分法,直接从中心点查找,第二次变成1/4的矩阵继续查找中心点。
写完才发现这个思路有问题,中心点查找完是只缩小1/4的面积,因此修改成了一个递归处理的方式,中心查找完成后,对3个1/4面积分别中心查找,进行递归,代码如下。
class Solution {
public:
bool findThird(int x1,int x2,int y1,int y2,int target, vector<vector<int> > array){
if(x1==x2&&y1==y2)
return (target==array[x1][y1])?true:false;
if(x1==x2){
for(int i=y1;i<=y2;i++){
if(target==array[x1][i]) return true;
}
return false;
}
if(y1==y2){
for(int i=x1;i<x2;i++){
if(target==array[i][y1]) return true;
}
return false;
}
if (target > array[(x1 + x2) / 2][(y1 + y2) / 2]) {
bool a1=false,a2=false,a3=false;
if((y1+y2)/2<y2)
a1 = findThird(x1, (x1+x2)/2, (y1+y2)/2+1, y2, target, array);
if((x1+x2)/2<x2)
a2 = findThird((x1+x2)/2+1, x2, y1, (y1+y2)/2, target, array);
if(((y1+y2)/2<y2)&&((x1+x2)/2<x2))
a3 = findThird((x1+x2)/2+1, x2, (y1+y2)/2+1, y2, target, array);
return a1||a2||a3;
} else if (target < array[(x1 + x2) / 2][(y1 + y2) / 2]) {
bool a1=false,a2=false,a3=false;
//边缘判断
if(((x1+x2)/2>x1) && ((y1+y2)/2>y1))
a1 = findThird(x1, (x1+x2)/2-1, y1, (y1+y2)/2-1, target, array);
if((x1+x2)/2>x1)
a2 = findThird(x1, (x1+x2)/2-1, (y1+y2)/2, y2, target, array);
if((y1+y2)/2>y1)
a3 = findThird((x1+x2)/2, x2, y1, (y1+y2)/2-1, target, array);
return a1||a2||a3;
} else
return true;
}
bool Find(int target, vector<vector<int>> array) {
return findThird(0, array.size()-1, 0, array[0].size()-1, target, array);
}
};
换一种思考方式
早一点换其他思路就不用浪费这么长的时间了啊。
直接从一个角开始查找,取右上角,右上角如果小于目标,则目标在最右一列,若大于则矩阵去掉最右面的一列继续查找。
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
int rows = array.size();
int cols = array[0].size();
if(!array.empty() && rows > 0 && cols > 0){
int row = 0;
int col = cols - 1;
while(row < rows && col >= 0){
if(array[row][col] == target){
return true;
}
else if(array[row][col] > target){
--col;
}
else{
++row;
}
}
}
return false;
}
};