字节面试题之二维数组中的查找

373 阅读2分钟

题目:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

分析:本题其实就是剑指offer上的面试题4,面试时用书上的解法写完后面试官觉得效率不够好,要求我用二维二分查找重写一遍,当时没在牛客网验证,今天同学问到,刚好重写了一遍,记录一下。

思路:每次找到整个数组处于中间的元素,和target比较大小

如果相等,返回true
如果比target大,对该元素左上方的矩阵[图中的1模块]重复查找操作
如果比target小,对该元素下方[图中的2模块]和右方[图中的3模块]的矩阵重复查找操作

注意的点

1.边界条件

2.判断二维矩阵是否为空的方式,我一开始只判断了行不为0即止,导致上牛客网时提示段错误,忽略了行大小不为0,列大小为0的情况:[[];[];[];[]]

代码

class Solution {
public:
    bool Find(int target, vector<vector<int>> array) 
    {
        int row = array.size();
		if (row == 0)
			return false;
		int colum = array[0].size();
        if(colum == 0)
            return false;
		bool sign = findNum(target, array, 0, 0, row - 1, colum - 1);
		return sign;
    }
    
    bool findNum(int target,vector<vector<int>> & array,int iBegin,int jBegin,int iEnd,int jEnd)
    {
		//计算中间元素下标
		int iMed = (iBegin + iEnd) / 2;
		int jMed = (jBegin + jEnd) / 2;

		if (target == array[iMed][jMed])
			return true;
		else if (array[iMed][jMed] > target)
		{
			if ((iBegin == iMed) && (jBegin == jMed))
				return false;
			else
				return findNum(target, array, iBegin, jBegin, iMed, jMed);
		}
		else
		{
			bool sign1 = false;
			bool sign2 = false;
			if (iMed != iEnd)
				sign1 = findNum(target, array, iMed + 1, jBegin, iEnd, jMed);
			if (jMed != jEnd)
				sign2 = findNum(target, array, iBegin, jMed + 1, iEnd, jEnd);
			return ( sign1 || sign2);
		}
    }
};