C++
判断数组是否为空
运用判断条件 matrix.size()==0 || matrix[0].size()==0 进行判断,判断时从左到右执行,如果 matrix 为空,不会引用到 matrix[0],所以就不会发生下标越界的情况。
实现
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
if(matrix.size()==0 || matrix[0].size()==0) return false;
int m=matrix.size(); //行数
int n=matrix[0].size(); //列数
int i=0,j=n-1;
while(j>=0 && i<m){
if(matrix[i][j]>target) {
j--;
}
else if(matrix[i][j]<target){
i++;
}
else return true;
}
return false;
}
};
Java
题目
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
分析
我在分析这个问题的时候,第一步首先想到的是,在纸上把代表二维数组的矩形画出来,然后分别查找第一行和第一列最先大于target值的行列坐标,这样可以把搜索范围确定在矩形的左上角。当然由于我没有给出测试用例,考虑的不周到,首先这样做在面对查找大数的时候跟全盘搜索没有区别,第一行第一列所有的数字都小于我要查找的target,相当于遍历全数组搜索。
笔记
下面对《剑指offer》书上对这个题的详解进行转述和记录:
当我们面对一个问题时,我们首先应该想到是化繁为简,具体问题具体分析。通过分析简单的例子,试图寻找普遍的规律。现在如果我们从数组的一个角上选取数字来和要查找的数字做比较,这样做会不会更简单呢?如下所示的测试用例,我们需要在其中查找数字7:
1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15
首先,我们选取数组右上角的数字9。由于9大于7,并且9还是第四列的第一个数字,也是该列当中最小的数字,因此7不可能出现在第四列。于是我们可以把第四列从搜索范围当中剔除,之后只需要考虑剩下的三列即可。在剩下的矩阵当中,右上角的数字为8,8位第三列的第一个数字。同上,我们可以把第三列从搜索范围当中剔除。
在剩下两列组成的数组当中,数字2位于数组的右上角。由于2是该数组第一行最后一个数字(也是最大的)数字,因此7不可能出现在数字2所在的行。于是我们可以把数字2所在的行剔除,只剩下三行两列的数字。在剩下的数组当中,4位于右上角,同上,我们把数字4所在的行也删除,最后剩下两行两列数字。
4 7
6 8
在剩下的数组当中,位于右上角的7刚好就是我们要查找的数字,于是查找过程结束。
同样,我们也可以选取左下角的数字。
1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15
数字6小于7,剔除6所在的列:
2 8 9
4 9 12
7 10 13
8 11 15
数字8大于7,剔除8所在的行:
2 8 9
4 9 12
7 10 13
查找到数字7,查找完成。
代码
public class Solution {
public boolean Find(int target, int [][] array) {
Boolean found=false;
int rows=array.length;
int columns=array[0].length;
if(array.length!=0 && rows>0 && columns>0){
int row=0;
int column=columns-1;
while(row<rows && column>=0){
if(array[row][column]==target)
{
found=true;
break;
}
else if(array[row][column]>target)
--column;
else ++row;
}
}
return found;
}
}
测试用例
- 二维数组中包含查找的数字(查找的数字是数组中的最大值和最小值,查找的数字介于数组中的最大值和最小值之间)。
- 二维数组中没有查找的数字(查找的数字大于数组中的最大值,查找的数字小于数组中的最小值,查找的数字在数组的最大值和最小值之间但是数组中没有这个数字)。
- 特殊测试用例(输入空指针)。