【数据结构】求矩阵中马鞍数的几种方法
题目如下:
请写一个程序,找出给定矩阵的马鞍点。
注 :若一个矩阵中的某元素在其所在行最小而在其所在列最大,则该元素为矩阵的一个马鞍点。
针对这道题,我们常用也最常见到的有两种方法,除了这两种方法之外,这里笔者还会给出自己证明推导后得出的第三种方法。
首先列出比较常见的两种方法。
思路一
时间复杂度 : O(N^3)
思路一是最容易想到的, 即对矩阵中的每一个元素点做判断, 若该元素既是其所在行的最小值, 同时也是其所在列的最大值, 则该点为矩阵中的一个马鞍点。
下面贴出代码,不做注释
//@author:MER
void saddlePoint_one(vector<vector<int>> &matrix) {
for (int i = 0; i != ROW; i++) {
for (int j = 0; j != COL; j++) {
cout << matrix[i][j] << "\t" << ends;
}
cout << endl;
}
bool flag = true;
for (int i = 0; i != ROW; i++) {
for (int j = 0; j != COL; j++) {
int k = 0, temp = matrix[i][j];
flag = true;
for (k = 0; k != COL; k++) {
if (temp > matrix[i][k]) {
flag = false;
break;
}
}
for (k = 0; flag == true && k != ROW; k++) {
if (temp < matrix[k][j]) {
flag = false;
break;
}
}
if (flag) {
cout << "matrix[" << i << "][" << j << "] :" << matrix[i][j] << " 为马鞍数" << endl;
}
}
}
}
思路二
时间复杂度:O(N^2)
这种思路采取了以空间换时间的思路,用两个一维数组row_min[ROW] 与 col_max[COL] 分别保存 每行的最小值 与 每列的最大值, 之后再比对两个数组中的值来找出符合条件的马鞍数
//@author:MER
void saddlePoint_two(vector<vector<int>> &matrix) {
int row_min[ROW], col_max[COL];
for(int i = 0; i != ROW; i++)
row_min[i] = matrix[i][0];
for(int i = 0; i != COL; i++)
col_max[i] = matrix[0][i];
for (int i = 0; i != ROW; i++)
{
for (int j = 0; j != COL; j++) {
if (row_min[i] > matrix[i][j]) row_min[i] = matrix[i][j];
if (col_max[j] < matrix[i][j]) col_max[j] = matrix[i][j];
}
}
for (int i = 0; i != ROW; i++){
for (int j = 0; j != COL; j++) {
if (row_min[i] == col_max[j])
{
cout << "matrix[" << i << "][" << j << "] :" << matrix[i][j] << " 为马鞍数" << endl;
}
}
}
}
思路三
时间复杂度 : O(N)
第二种思路基本上已经把问题在统计方面的复杂度压缩在了一个可控的范围内,而思路三正是在思路二的基础上,对row_min与col_max的比对过程做了进一步的优化。
这种思路是我偶然间思索得到的。在网上查找类似的方法时并没有找到,因此对于这种思路涉及到的过程,我将在此给予证明及详细注释,如果有不恰当甚至错误的地方,请各位指证,以免误导他人。
首先在矩阵的处理上,依旧同思路二一样,用一维数组row_min[ROW]保存 每行的最小值, 用col_max[COL]保存 每列的最大值。
接下来是一系列简单的证明过程,我将证明出在严格意义上,一个矩阵中马鞍点的数量至多只能有一个, 并且 若马鞍点存在,其一定是row_min中的最大值, 同时是col_max中的最小值。
首先证明一个矩阵中至多只有一个马鞍点:
给出一个矩阵matrix[M][N]如下