我有一个任务。我需要找到具有相同数字的最大区域(例如,按行或列的邻居)。我制作的程序运行正常,但问题是如果我有以下矩阵:
{ 1, 3, 2, 2, 2, 4 }
{ 3, 1, 3, 2, 4, 4 }
{ 4, 3, 1, 2, 3, 3 }
{ 4, 3, 1, 3, 3, 1 }
{ 4, 3, 3, 3, 1, 1 }
该程序将打印10.Okay也许你们中的一些人可能会说这是因为我在最终结果中加1,是的,如果我没有加1,如果我在位置[1] [1] ]是3而不是1,我会得到12个女巫是错的,所以这就是为什么我添加1.所以我的问题是你有任何关于优化算法的建议..是的,我会非常感谢听到他们:) ..
Here is my code:
protected int counter = 0;
protected int max = 1;
protected enum eState {
Vi,
InPr,
Unvi
};
public void recNodeMatrix(int i, int j, eState st[][],int [][]matr,int n,int k) {
st[i][j] = eState.InPr;
for (int r = 0; r < n; r++) {
for (int c = 0; c < k; c++) {
if ((matr[i][j] == matr[r][c])
&& ((((i+j) - (r + c)) == 1) || (((i+j) - (r + c)) == -1))
&& ((st[r][c] == eState.Unvi))) {
counter++;
recNodeMatrix(r, c, st,matr,n,k);
}
}
}
st[i][j] = eState.Vi;
}
public void Zad17() {
int n=5,k=6;
eState st[][] = new eState[n][k];
int[][] matr = new int[][] {
{ 1, 3, 2, 2, 2, 4 },
{ 3, 1, 3, 2, 4, 4 },
{ 4, 3, 1, 2, 3, 3 },
{ 4, 3, 1, 3, 3, 1 },
{ 4, 3, 3, 3, 1, 1 } };
for (int i = 0; i < n; i++) {
for (int j = 0; j < k; j++) {
st[i][j] = eState.Unvi;
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < k; j++) {
if(st[i][j] == eState.Unvi) {
recNodeMatrix(i, j, st,matr,n,k);
if(max<counter)
max=counter;
counter =0;
}
}
}
System.out.print(max+1);
}
答案 0 :(得分:1)
解决此问题的最佳方法可能是使用union-find数据结构:https://en.wikipedia.org/wiki/Disjoint-set_data_structure
最初,每个单元格都是它自己的集合,然后合并每组具有相同数字的相邻单元格的集合。
当你完成时,答案就是最大集合的大小。由于您必须始终跟踪设置的大小,因此请使用union-by-size而不是union-by-rank。
应用一点聪明,你可以用一个N * K整数数组实现union-find - 每个单元一个。每个整数都是父集的索引或-size for roots。
这解决了大约线性时间的问题,并且在实践中可能比使用相似内存量的泛洪填充解决方案更快。