Java 用DFS算法求矩阵中相邻数的最大面积

Java 用DFS算法求矩阵中相邻数的最大面积,java,algorithm,matrix,Java,Algorithm,Matrix,我正在自学一本初学者用的书。我在“数组”一章之后的最后一项任务是: // Find the biggest area of adjacent numbers in this matrix: int[][] matrix = { {1,3,2,2,2,4}, {3,3,3,2,4,4}, {4,3,1,2,3,3}, // --->13 times '3'; {4,3,1,3,3,1}, {4,3,3,3,1,

我正在自学一本初学者用的书。我在“数组”一章之后的最后一项任务是:

 // Find the biggest area of adjacent numbers in this matrix:
int[][] matrix = {
        {1,3,2,2,2,4},
        {3,3,3,2,4,4},
        {4,3,1,2,3,3}, // --->13 times '3';
        {4,3,1,3,3,1},
        {4,3,3,3,1,1}
作为提示,我已经使用了DFS或BFS算法。在我读了关于它们的文章并看到了它们的许多实现之后,我有了这个想法,但对于初学者来说,这实在是太难了。我为我的任务找到了解决方案,在我运行了很多次程序之后,我明白了它是如何工作的,现在我可以自己解决这个问题了。虽然,我很高兴这个解决方案帮助我学习了递归,但我想知道下面的代码能否以迭代的方式进行修改,如果可以的话,你能给我一些提示吗?先谢谢你

public class Practice {

private static boolean[][] visited = new boolean[6][6];
private static int[] dx = {-1,1,0,0};
private static int[] dy = {0,0,-1,1};
private static int newX;
private static int newY;

public static void main(String[] args){
 // Find the biggest area of adjacent numbers in this matrix:
 int[][] matrix = {
        {1,3,2,2,2,4},
        {3,3,3,2,4,4},
        {4,3,1,2,3,3}, // --->13 times '3';
        {4,3,1,3,3,1},
        {4,3,3,3,1,1}

};

int current = 0;
int max = 0;

for (int rows = 0; rows < matrix.length;rows++){
    for(int cols = 0; cols < matrix[rows].length;cols++){

        if (visited[rows][cols] == false){
            System.out.printf("Visited[%b] [%d] [%d] %n", visited[rows]
       [cols],rows,cols);
            current = dfs(matrix,rows,cols,matrix[rows][cols]);
            System.out.printf("Current is [%d] %n", current);
            if(current > max){
                System.out.printf("Max is : %d %n ", current);
                max = current;
            }

        }
    }   
}       
        System.out.println(max);
}
static int dfs(int[][] matrix,int x, int y, int value){         

    if(visited[x][y]){
        System.out.printf("Visited[%d][%d] [%b] %n",x,y,visited[x][y]);
        return 0;
    } else {
        visited[x][y] = true;
        int best = 0;
        int bestX = x;
        int bestY = y;

        for(int i = 0; i < 4;i++){
             //dx = {-1,1,0,0};
             //dy = {0,0,-1,1};
            int modx = dx[i] + x;
            System.out.printf(" modx is : %d %n", modx);
            int mody = dy[i] + y;
            System.out.printf(" mody is : %d %n", mody);
            if( modx == -1 || modx >= matrix.length || mody == -1 || mody >= 
             matrix[0].length){
                continue;
            }
            if(matrix[modx][mody] == value){
                System.out.printf("Value is : %d %n",value);
                int v = dfs(matrix,modx,mody,value);
                System.out.printf(" v is : %d %n",v);
                best += v;
                System.out.printf("best is %d %n",best);
            }

            newX = bestX;
            System.out.printf("newX is : %d %n",newX);
            newY = bestY;
            System.out.printf("newY is : %d %n",newY);
        }
        System.out.printf("Best + 1 is  : %d %n ",best + 1);
            return best + 1;
    }


}
}
公共课堂实践{
私有静态布尔值[][]已访问=新布尔值[6][6];
私有静态int[]dx={-1,1,0,0};
私有静态int[]dy={0,0,-1,1};
私有静态int-newX;
私有静态int-newY;
公共静态void main(字符串[]args){
//在此矩阵中查找相邻数字的最大面积:
int[][]矩阵={
{1,3,2,2,2,4},
{3,3,3,2,4,4},
{4,3,1,2,3,3},/-->13次'3';
{4,3,1,3,3,1},
{4,3,3,3,1,1}
};
int电流=0;
int max=0;
for(int rows=0;rows最大值){
System.out.printf(“最大值为:%d%n”,当前值);
最大值=电流;
}
}
}   
}       
系统输出打印项次(最大值);
}
静态int dfs(int[][]矩阵,int x,int y,int值){
如果(访问[x][y]){
System.out.printf(“已访问[%d][%d][%b]%n”,x,y,已访问[x][y]);
返回0;
}否则{
访问[x][y]=真;
int-best=0;
int-bestX=x;
int-bestY=y;
对于(int i=0;i<4;i++){
//dx={-1,1,0,0};
//dy={0,0,-1,1};
int modx=dx[i]+x;
System.out.printf(“modx是:%d%n”,modx);
int mody=dy[i]+y;
System.out.printf(“mody是:%d%n”,mody);
如果(modx=-1 | | modx>=matrix.length | | mody==-1 | | mody>=
矩阵[0]。长度){
继续;
}
if(矩阵[modx][mody]==值){
System.out.printf(“值为:%d%n”,值);
int v=dfs(矩阵,modx,mody,值);
System.out.printf(“v为:%d%n”,v);
最佳+=v;
System.out.printf(“最佳为%d%n”,最佳);
}
newX=bestX;
System.out.printf(“newX是:%d%n”,newX);
纽伊=贝蒂;
System.out.printf(“newY是:%d%n”,newY);
}
System.out.printf(“最佳+1为:%d%n”,最佳+1);
返回最佳+1;
}
}
}

如果您在Wikipedia页面的伪代码部分下查看,他们有一个DFS算法迭代验证的示例。应该能够从那里找到解决方案

*编辑

要使其迭代,可以执行以下操作:

procedure DFS-iterative(matrix, x, y):
  let S be a stack
  let value = 0
  if !visited[v.x, v.y]
    S.push(position(x,y))
  while S is not empty
    Position v = S.pop()
    value += 1
    for all valid positions newPosition around v 
      S.push(newPosition)
  return value
每次在递归方法中调用
dfs()
方法时,都应该调用
S.push()
。您可以按如下方式创建类位置

class Position{
  int x;
  int y;
  public Position(int x, int y){
    this.x = x;
    this.y = y;
  }
  //getters and setters omitted for brevity
}
并使用内置的java类
java.util.Stack
使其变得简单

Stack s=新堆栈()


如果您想使用BFS而不是DFS,您可以简单地将堆栈更改为队列,从而获得所需的结果。对堆栈和队列有一个很好的解释,当您了解该主题时,可能会被证明很有用。

我假设您正在寻找BFS解决方案,因为您已经有了一个工作的DFS,并且BFS是迭代的,而DFS是递归的(或者至少更容易递归实现)

测量区域大小的(未经测试的)BFS代码可以是:

public static int regionSize(int[][] matrix, 
        int row, int col, HashSet<Point> visited) {

    ArrayDeque<Point> toVisit = new ArrayDeque<>();
    toVisit.add(new Point(col, row));
    int regionColor = matrix[col][row];
    int regionSize = 0;
    while ( ! toVisit.isEmpty()) {
      Point p = toVisit.removeFirst(); // use removeLast() to emulate DFS
      if ( ! visited.contains(p)) {
         regionSize ++;
         visited.add(p);
         // now, add its neighbors
         for (int[] d : new int[][] {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}) {
            int nx = p.x + d[0];
            int ny = p.y + d[1];
            if (nx >= 0 && nx < matrix[0].length 
                && ny >= 0 && ny < matrix.length 
                && matrix[ny][nx] == regionColor) {
                toVisit.addLast(new Point(nx, ny)); // add neighbor
            }
         }
      }
   }
   return regionSize;
}
public static int regionSize(int[][]矩阵,
int行、int列、哈希集){
ArrayDeque toVisit=新的ArrayDeque();
添加(新点(列,行));
int regionColor=矩阵[col][row];
int regionSize=0;
而(!toVisit.isEmpty()){
点p=toVisit.removeFirst();//使用removeLast()模拟DFS
如果(!visted.contains(p)){
regionSize++;
添加(p);
//现在,添加它的邻居
对于(int[]d:newint[][{{1,0},{0,1},{-1,0},{0,-1}}){
int nx=p.x+d[0];
int-ny=p.y+d[1];
如果(nx>=0&&nx<矩阵[0]。长度
&&ny>=0&&ny
请注意,通过更改单行,可以将(基于队列的)BFS更改为迭代DFS。在递归DFS中,您将使用程序堆栈跟踪显式堆栈/deque的
toVisit
intead。您可以通过添加一个
System.out.println
跟踪算法的进度来测试这一点


在上面,我使用了
的散列集,而不是
布尔[][]
数组,但是可以随意使用对您来说最简单的数组

OP已经有一个正在工作的DFS。OP要求提供指向BFS解决方案的指针。是的,维基百科有伪代码,但只链接的答案是不受欢迎的,至少应该包括他们链接到的任何东西的论点要点。刚刚编辑。因为我对这一点还不熟悉,这是否更接近于@tucuxi回答问题的方式?请注意,通常y表示列,x表示行;同样地,您可以使用
modx>=matrix[0].length
mody>=matrix.length