当前位置: 首页 > 知识库问答 >
问题:

1的最大区域的单位面积

韩宜春
2023-03-14

考虑一个N行M列的矩阵,其中每个单元格包含一个“0”或一个“1”,任何包含1的单元格都称为填充单元格。如果两个单元在水平、垂直或对角线上相邻,则称它们是相连的。如果一个或多个填充的单元格连接在一起,它们就形成了一个区域。任务是找到最大区域的单位面积。

下面是我的代码:

class GFG {
    static int max;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
        for (int t = 0; t < T; t++) {
            max = 1;
            int R = sc.nextInt();
            int C = sc.nextInt();
            int[][] M = new int[R][C];
            for (int i = 0; i < R; i++) {
                for (int j = 0; j < C; j++) {
                    M[i][j] = sc.nextInt();
                }
            }
            printMatrix(M, R, C);
            boolean[][] visited = new boolean[R][C];
            for (int i = 0; i < R; i++) {
                for (int j = 0; j < C; j++) {
                    int L = 1;
                    if (M[i][j] == 1 && !visited[i][j])
                        markVisited(M, visited, i, j, R, C, L);
                }
            }
            System.out.println(max);
        }
    }

    private static void printMatrix(int[][] M, int R, int C) {
        for (int i = 0; i < R; i++) {
            for (int j = 0; j < C; j++) {
                System.out.print(M[i][j] + " ");
            }
            System.out.println();
        }

    }

    public static boolean isSafe(int[][] M, boolean[][] visited, int i, int j, int R, int C) {
        return ((i >= 0 && i < R) && (j >= 0 && j < C) && (M[i][j] == 1 && (!visited[i][j])));
    }

    public static void markVisited(int[][] M, boolean[][] visited, int x, int y, int R, int C, int L) {
        // int[] x_pos = {1 , 1, 1, 0, 0, -1, -1, -1};
        // int[] y_pos = {-1, 0, 1, -1, 1, -1, 0, 1};
        //commenting the arrays, as selecting one of the above and below combinations, result in different outputs
        int[] x_pos = { -1, -1, -1, 0, 0, 1, 1, 1 };
        int[] y_pos = { -1, 0, 1, -1, 1, -1, 0, 1 };

        visited[x][y] = true;
        for (int k = 0; k < 8; k++) {
            if (isSafe(M, visited, x + x_pos[k], y + y_pos[k], R, C)) {
                L++;
                max = Math.max(L, max);
                markVisited(M, visited, x + x_pos[k], y + y_pos[k], R, C, L);
            }
        }

    }
}

下面提到的测试用例的代码不起作用:
1
4 7
1 1 1 1 0 0 1 1 0 1 0 0 0 1 0 1 0 0 1 1 1 1 1
输出为13,预期为14。
有趣的是,如果我将markVisited方法中的x_pos和y_pos(在代码中注释)更改为

int[] x_pos = {1 , 1, 1, 0, 0, -1, -1, -1};  
int[] y_pos = {-1, 0, 1, -1, 1, -1, 0, 1};

输出为14。我不明白当x_pos和y_pos组合相同时,输出如何改变。
其他测试用例也会发生这种情况。我已经评论了x_pos[]和y_pos[]。
请指出有什么问题。

共有1个答案

微生永春
2023-03-14

所以,你的问题是你递归累加L的方式。下面是您的输入数组:

1 1 1 1 0 0 1

1 0 1 0 1 1 0

0 0 0 0 1 0 1

1 0 0 0 1 1 1

举个例子。如果您已经积累的路径被拆分为两个不同的路径(让我们拾取您输入的前3行以便更好地理解)

0 0 0 0 1 0 1

在位置(1,5)处,您可以转到右上的1或右下的1(您的路径被一分为二),您将当前的L传递给这些路径中的每一个,然后,这些路径各自累加L,而不是累加全局L,全局L用于累加属于主路径的所有1,主路径的根是您找到的第一个1。

您的修复非常简单,只需将L移动到变量的顶部,如下所示:

static int max;
static int L;

那么,每次启动一个新根1时,只需重新设置它的值,而不是通过您的方法传递L:

if (M[i][j] == 1 && !visited[i][j]) {
    L = 1;
    markVisited(M, visited, i, j, R, C);
}

最后,在您的markVisited中,只需执行与您所做的相同的操作,但在您的方法末尾去掉那个L参数,因为您将使用全局参数:

max = Math.max(++L, max);

希望有帮助,如果不清楚请告诉我,以便在需要时添加更多详细信息^-^

 类似资料:
  • 给定n个非负整数a1, a2,..., an,其中每个表示坐标(i, ai)处的点。绘制n条垂直线,使得线i的两个endpoint位于(i, ai)和(i,0)。找到两条线,它们与x轴一起构成一个容器,使得容器中包含最多的水。 注意:容器不能倾斜。 一种解决方案可能是我们取每一行并找到每一行的区域。这需要O(n^2)。没有时间效率。 另一种解决方案是使用DP找到每个索引的最大面积,然后在索引n处,

  • 问题内容: 在研究G1 GC时,我发现了这篇文章:http : //www.oracle.com/technetwork/articles/java/g1gc-1984535.html。在该文章中,内容如下: G1 GC是一个区域化的,按代划分的垃圾收集器,这意味着Java对象堆(堆)被划分为多个大小相等的区域。启动时,Java虚拟机(JVM)设置区域大小。区域大小可以从1 MB到32 MB不等,

  • 本文向大家介绍opencv 查找连通区域 最大面积实例,包括了opencv 查找连通区域 最大面积实例的使用技巧和注意事项,需要的朋友参考一下 今天在弄一个查找连通的最大面积的问题。 要把图像弄成黑底,白字,这样才可以正确找到。 然后调用下边的方法: RETR_CCOMP:提取所有轮廓,并将轮廓组织成双层结构(two-level hierarchy),顶层为连通域的外围边界,次层位内层边界 方法二

  • 一、题目 输入数字n,按顺序打印出从1到n位最大十进数的数值。比如输入3,则打印出1、2、3一直到最大三位数即999。 二、解题思路 ①使用一个n位的数组来存储每一位的元素。例如n位3,则000表示为[0,0,0]。 使用递归的方式,存放每一位元素值。 ②同上,使用一个n位的数组来存储每一位的元素。然后循环执行加1运算,并在数组中进行模拟进位,直到最高位需要进位,则表示循环结束。 三、解题代码 p

  • 题目描述 输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数即 999。 解题思路 由于 n 可能会非常大,因此不能直接用 int 表示数字,而是用 char 数组进行存储。 使用回溯法得到所有的数。 // java public void print1ToMaxOfNDigits(int n) { if (n <= 0)

  • 本文向大家介绍如何放大点击的区域?相关面试题,主要包含被问及如何放大点击的区域?时的应答技巧和注意事项,需要的朋友参考一下