我正在寻找一种算法来查找NxN矩阵中所有鞍点的位置。
通过搜索StackOverflow上的其他答案以及其他常规站点,我只找到了关于在一个方向上运行的鞍点的解决方案。也就是说,我想找到一个鞍点,它的行可以是最大值,列中可以是最小值,也可以是行中的最小值和列中的最小值。
例如,给定:
array = {
{ 10, 15, 20, 15, 10 }
{ 5, 10, 15, 10, 5 }
{ 0, 5, 10, 5, 0 }
{ 5, 10, 15, 10, 5 }
{ 10, 15, 20, 15, 10 } },
鞍点是角落里的10点和中间的10点。
我可以很容易地找到它们,但我想要更高效的东西。我被告知可以在O(n ^ 2)中完成。
我想也许我可以修复x坐标并迭代y坐标来找到所有的最大值和最小值,然后通过修复y坐标并迭代x坐标来反转过程,但我不能非常可视化,足以实现这个想法。
非常感谢任何帮助。
答案 0 :(得分:1)
请注意,在天真的实现O(n 3 )中,您将重新计算您经历的行/列的每个元素的最大值和最小值。
为了消除这种低效率,我们的想法是遍历每一行和每一行,并在一个单独的N×N数组中用最大值和最小值标记所有位置。此单独数组的每个元素包含2条布尔信息:isMax
和isMin
(如果您愿意,可以将其编码为位)。如果行/列中的所有元素都相同(即最大值=最小值),那么您可能不想标记任何元素。
对于每一行/列,这可以在O(n)时间内完成。使用n元素数组记录当前最大(最小)值的索引,如果存在比当前最大值(最小值)更大(更小)的值,则清除数组。完成循环后,使用最大(最小)索引数组中的信息标记N x N数组中相应的isMax
(isMin
)字段。
由于有n行和n列,因此该步骤的复杂度为O(n 2 )
然后剩下的就是遍历已标记的N x N数组,以搜索设置了isMax
和isMin
的任何位置。
答案 1 :(得分:1)
为O(n ^ 2)
#include <stdio.h>
#define N 8
#define M 10
int arr[N][M] =
{ {1,2,0,3,9,4,5,3,6,7},
{2,4,3,5,9,0,2,3,4,1},
{5,3,4,7,6,1,9,0,4,2},
{6,9,7,8,6,7,7,4,5,6},
{8,3,1,9,2,0,6,2,8,2},
{2,7,3,0,3,6,3,1,5,3},
{8,2,5,9,7,7,8,3,7,3},
{1,7,4,8,5,8,5,0,0,6} };
int FindSaddlePoints(int arr[N][M])
{
int l_result = 0;
int l_row[M], l_column[N], i, j, index;
//find the min
for (i = 0; i < N; i++)
{
index = 0;
for (j = 1; j < M; j++)
{
if (arr[i][j] < arr[i][index])
{
index = j;
}
}
l_column[i] = index;
}
for (j = 0; j < M; j++)
{
index = 0;
//find the max
for (i = 1; i < N; i++)
{
if (arr[i][j] > arr[index][j])
{
index = i;
}
}
l_row[j] = index;
}
for (i = 0; i < N; i++)
{
for (j = 0; j < M; j++)
{
if (l_row[j] == i && l_column[i] == j && i != N && j != M)
{
//printf("found in row = %d column = %d", i, j);
l_result++;
}
}
}
return l_result;
}
void main()
{
int number = FindSaddlePoints(arr);
printf("%d", number);
}