行列递增矩阵的查找

题目描述


在一个mn列的二维数组中,每一行都按照从左到右递增的顺序排列,每一列都按照从上到下递增的顺序排列。现输入这样的一个二维数组和一个整数,请完成一个函数,判断数组中是否含有该整数。例如,给定如图4-1所示的二维数组,它的每一行每一列都递增排序。如果在这个数组中查找数6,则返回true;如果查找数5,则由于该数组不含有数5,返回false。


行列递增矩阵的查找(面试题)_杨氏矩阵


分析与解法


这种行和列分别递增的矩阵,有一个专有名词叫做杨氏矩阵,是由剑桥大学数学家杨表在1900年提出的,而在这个矩阵中的查找俗称杨氏矩阵的查找。

解法一:分治法

以查找数6为例,因为矩阵的行和列都是递增的,所以整个矩阵的对角线上的数也是递增的,故可以在对角线上进行二分查找:如果要找的数的大小介于对角线上相邻的两个数之间,则可以排除掉左上和右下的两个小矩阵,而在左下和右上的两个小矩阵内继续递归查找,如图4-2所示。


行列递增矩阵的查找(面试题)_面试题_02


解法二:定位法

如图 4-3所示,首先直接定位到矩阵中最右上角的元素,如果这个元素比要找的数6大就往左走,比要找的数6小就往下走,直到找到要找的数6为止。这个方法的时间复杂度是O(m +n)。



行列递增矩阵的查找(面试题)_数组_03


代码:

#define ROW 4
#define COL 4

bool YoungMatrix(int array[][COL], int searchKey)
{
int i = 0, j = COL - 1;
int var = array[i][j];
while (true)
{
if (var == searchKey)
{
return true;
}
else if (var < searchKey && i < ROW - 1)
{
var = array[++i][j];
}
else if (var > searchKey && j > 0)
{
var = array[i][--j];
}
else
{
return false;
}
}
}


举一反三

求中位数

给定n×n的实数矩阵,它的每行和每列都是递增的,求这n2个数的中位数。

杨氏矩阵的构成

我们已经知道杨氏矩阵中每行的元素从左到右单调递增,每列的元素从上到下也单调递增。那么,如果给定1~nn个数,可以构成多少个杨氏矩阵呢?例如,n=4时,可以构成4个矩阵,一个1行4列的矩阵:


行列递增矩阵的查找(面试题)_行列递增矩阵的查找_04