C# 在我的算法中,在0和1的数组中查找1的最大连通区域的大小的缺陷在哪里?
例如,如果数组是C# 在我的算法中,在0和1的数组中查找1的最大连通区域的大小的缺陷在哪里?,c#,algorithm,C#,Algorithm,例如,如果数组是 1 1 0 0 0 1 1 0 0 0 1 0 1 0 0 0 那么答案是5 我有一个助手函数 // Returns the size of the region of 1s containing the point (x0, y0). // For example, if mat = 0 0 1 // 1 0 0 // 1 1 1 // then max_connected_regio
1 1 0 0
0 1 1 0
0 0 1 0
1 0 0 0
那么答案是5
我有一个助手函数
// Returns the size of the region of 1s containing the point (x0, y0).
// For example, if mat = 0 0 1
// 1 0 0
// 1 1 1
// then max_connected_region(0,0,mat) = 0,
// max_connected_region(2,0,mat) = 1,
// and max_connected_region(0,1,mat) = 4
static int max_connected_region(int x0, int y0, int[,] mat)
{
if(mat[x0,y0] == 0)
return 0;
var surroundings = (new int[][] {
new int[] { x0 - 1, y0 }, new int[] {x0 + 1, y0 },
new int[] { x0 - 1, y0 + 1}, new int[] { x0, y0 + 1 }, new int[] {x0 + 1, y0 + 1},
new int[] { x0 - 1, y0 - 1}, new int[] { x0, y0 - 1 }, new int[] {x0 + 1, y0 - 1} }
).Where(pair => pair[0] >= 0 && pair[0] < mat.GetLength(0) && pair[1] >= 0 && pair[1] < mat.GetLength(1));
int count = 1;
foreach(var pair in surroundings)
count += max_connected_region(pair[0], pair[1], mat);
mat[x0,y0] = 0;
return count;
}
这个过程在测试用例中给了我一个超时或越界,我不知道为什么。因为,您的算法正在重新访问已经检查过的数组元素,将其放入一个无休止的循环中
实际上,您有一个程序语句似乎试图避免这种情况,但您在递归调用之后执行它。因此,它没有任何有用的效果。如果您只是将其移动到执行递归调用的循环之前,那么您的算法将工作:
static int max_connected_region(int x0, int y0, int[,] mat)
{
if (mat[x0, y0] == 0)
return 0;
var surroundings = (new int[][] {
new int[] { x0 - 1, y0 }, new int[] {x0 + 1, y0 },
new int[] { x0 - 1, y0 + 1}, new int[] { x0, y0 + 1 }, new int[] {x0 + 1, y0 + 1},
new int[] { x0 - 1, y0 - 1}, new int[] { x0, y0 - 1 }, new int[] {x0 + 1, y0 - 1} }
).Where(pair => pair[0] >= 0 && pair[0] < mat.GetLength(0) && pair[1] >= 0 && pair[1] < mat.GetLength(1));
int count = 1;
mat[x0, y0] = 0;
foreach (var pair in surroundings)
count += max_connected_region(pair[0], pair[1], mat);
return count;
}
它是怎样的
5
?你试图解释的逻辑是什么apply@un-幸运的是,它是1
s中最大的岛屿。你能解释一下你的算法应该如何工作吗?啊,我明白了。。在我看来像是无界递归。你检查一个单元的邻域,然后递归地检查它们的邻域,其中一个当然是原始单元。这并不是真正回答你的问题,但更好的方法是构建一个图,其中一个节点是一行中1
s的连续单元。如果两个节点位于连续的行上,并且有一个单元格属于同一列,则这两个节点是连接的。边的权重是两个节点中的单元数。所以这个图实际上是一个树的集合,你需要找到一个边和最大的树。
static int max_connected_region(int x0, int y0, int[,] mat)
{
if (mat[x0, y0] == 0)
return 0;
var surroundings = (new int[][] {
new int[] { x0 - 1, y0 }, new int[] {x0 + 1, y0 },
new int[] { x0 - 1, y0 + 1}, new int[] { x0, y0 + 1 }, new int[] {x0 + 1, y0 + 1},
new int[] { x0 - 1, y0 - 1}, new int[] { x0, y0 - 1 }, new int[] {x0 + 1, y0 - 1} }
).Where(pair => pair[0] >= 0 && pair[0] < mat.GetLength(0) && pair[1] >= 0 && pair[1] < mat.GetLength(1));
int count = 1;
mat[x0, y0] = 0;
foreach (var pair in surroundings)
count += max_connected_region(pair[0], pair[1], mat);
return count;
}
static int max_connected_region2(int x0, int y0, int[,] mat)
{
return max_connected_region2_impl(x0, y0, (int[,])mat.Clone());
}
static int max_connected_region2_impl(int x0, int y0, int[,] mat)
{
if (mat[x0, y0] == 0)
return 0;
int count = 1;
mat[x0, y0] = 0;
for (int i = 0; i < adjacentCells.Length; i++)
{
int[] pair = adjacentCells[i];
int x1 = pair[0] + x0, y1 = pair[1] + y0;
if (x1 >= 0 && x1 < mat.GetLength(0) && y1 >= 0 && y1 < mat.GetLength(1))
{
count += max_connected_region2_impl(x1, y1, mat);
}
}
return count;
}
private static readonly int[][] adjacentCells =
{
new [] { -1, 0 }, new [] { 1, 0 }, new [] { -1, 1 }, new [] {0, 1 },
new [] { 1, 1 }, new [] { -1, -1}, new [] { 0, -1 }, new [] { 1, -1 }
};