关于寻找矩阵中最大区域的练习的时间限制异常

Time Limit Exception on excercise about finding the largest area in matrix

https://judge.telerikacademy.com/problem/29largestareamatrix 这就是练习。 编写一个程序,找出矩形矩阵中相等相邻元素的最大面积并打印其大小。 输入

在第一行,您将收到由单个 space 分隔的数字 N 和 M 在接下来的 N 行中,将有 M 个数字,用 spaces 分隔 - 矩阵的元素

输出

打印等邻元素最大面积的大小

约束条件

3 <= N, M <= 1024 时间限制:0.5 秒 JAVA 内存限制:50MB

这是我的解决方案。

import java.util.Scanner;
import java.util.Stack;

public class Main {
    public static class Node {
        private int rowIndex, colIndex;

        Node(int rowIndex, int colIndex) {
            this.rowIndex = rowIndex;
            this.colIndex = colIndex;
        }

        Node[] getNeighbourNodes(int maxRowIndex, int maxColIndex) {
            Node[] nodes = new Node[4];

            int[][] indexesToCheck = {
                    {rowIndex - 1, colIndex},
                    {maxRowIndex - 1, colIndex},
                    {rowIndex + 1, colIndex},
                    {0, colIndex},
                    {rowIndex, colIndex - 1},
                    {rowIndex, maxColIndex - 1},
                    {rowIndex, colIndex + 1},
                    {rowIndex, 0}
            };

            for (int i = 0; i < indexesToCheck.length; i += 2) {
                int rowIndex = indexesToCheck[i][0], backupRowIndex = indexesToCheck[i + 1][0];
                int colIndex = indexesToCheck[i][1], backupColIndex = indexesToCheck[i + 1][1];
                if (indexExists(rowIndex, colIndex, maxRowIndex, maxColIndex)) {
                    nodes[i / 2] = new Node(rowIndex, colIndex);
                } else {
                    nodes[i / 2] = new Node(backupRowIndex, backupColIndex);
                }
            }

            return nodes;
        }

        private boolean indexExists(int row, int col, int maxRowIndex, int maxColIndex) {
            return row >= 0 && col >= 0 && row < maxRowIndex && col < maxColIndex;
        }
    }

    public static void main(String[] args) {
        Scanner keyboard = new Scanner(System.in);
        int n = keyboard.nextInt();
        int m = keyboard.nextInt();
        int[][] matrix = new int[n][m];
        boolean[][] visitedElements = new boolean[n][m];

        for (int row = 0; row < n; row++) {
            for (int col = 0; col < m; col++) {
                matrix[row][col] = keyboard.nextInt();
            }
        }

        int maxCounter = 0;
        for (int row = 0; row < n; row++) {
            for (int col = 0; col < m; col++) {
                if (!visitedElements[row][col]) {
                    maxCounter = Math.max(maxCounter, countAreaInMatrixDFS(row, col, matrix, visitedElements, n, m));
                }
            }
        }

        System.out.println(maxCounter);
    }

    private static int countAreaInMatrixDFS(int row, int col, int[][] matrix, boolean[][] visitedElements, int maxRowIndex, int maxColIndex) {
        Stack<Node> stack = new Stack<>();
        stack.push(new Node(row, col));
        visitedElements[row][col] = true;
        int counter = 1;

        while (stack.size() > 0) {
            Node currentNode = stack.pop();
            row = currentNode.rowIndex;
            col = currentNode.colIndex;

            Node[] neighboursIndexes = currentNode.getNeighbourNodes(maxRowIndex, maxColIndex);
            for (Node node : neighboursIndexes) {
                if (!visitedElements[node.rowIndex][node.colIndex] && matrix[row][col] == matrix[node.rowIndex][node.colIndex]) {
                    stack.push(node);
                    visitedElements[node.rowIndex][node.colIndex] = true;
                    counter++;
                }
            }
        }

        return counter;
    }
}

我在没有 Node class 和 BufferedReader 的情况下尝试过,但我仍然遇到时间限制异常。

import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.Arrays;
    import java.util.Stack;

    public class Main {
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String[] firstLine = br.readLine().split(" ");
            int n = Integer.parseInt(firstLine[0]);
            int m = Integer.parseInt(firstLine[1]);
            int[][] matrix = new int[n][m];
            boolean[][] visitedElements = new boolean[n][m];

            for (int row = 0; row < n; row++) {
                String[] line = br.readLine().split("\s");
                matrix[row] = Arrays.stream(line).mapToInt(Integer::parseInt).toArray();
            }

            int maxCounter = 0;
            for (int row = 0; row < n; row++) {
                for (int col = 0; col < m; col++) {
                    if (!visitedElements[row][col]) {
                        maxCounter = Math.max(maxCounter, countAreaInMatrixDFS(row, col, matrix, visitedElements, n, m));
                    }
                }
            }

            System.out.println(maxCounter);
        }

        private static int countAreaInMatrixDFS(int row, int col, int[][] matrix, boolean[][] checkedElements, int maxRowIndex, int maxColIndex) {
            Stack<Integer[]> stack = new Stack<>();
            stack.push(new Integer[]{row, col});
            checkedElements[row][col] = true;
            int counter = 1;

            while (stack.size() > 0) {
                Integer[] elementIndexes = stack.pop();
                row = elementIndexes[0];
                col = elementIndexes[1];

                int[][] neighboursIndexes = getNeighbourNodes(row, col, maxRowIndex, maxColIndex);
                for (int[] indexes : neighboursIndexes) {
                    int neighbourRow = indexes[0];
                    int neighbourCol = indexes[1];
                    if (!checkedElements[neighbourRow][neighbourCol] && matrix[row][col] == matrix[neighbourRow][neighbourCol]) {
                        stack.push(new Integer[]{neighbourRow, neighbourCol});
                        checkedElements[neighbourRow][neighbourCol] = true;
                        counter++;
                    }
                }
            }

            return counter;
        }

        private static int[][] getNeighbourNodes(int rowIndex, int colIndex, int maxRowIndex, int maxColIndex) {
            int[][] indexes = new int[4][];

            if (indexExists(rowIndex - 1, colIndex, maxRowIndex, maxColIndex)) {
                indexes[0] = new int[]{rowIndex - 1, colIndex};
            } else {
                indexes[0] = new int[]{maxRowIndex - 1, colIndex};
            }

            if (indexExists(rowIndex + 1, colIndex, maxRowIndex, maxColIndex)) {
                indexes[1] = new int[]{rowIndex + 1, colIndex};
            } else {
                indexes[1] = new int[]{0, colIndex};
            }

            if (indexExists(rowIndex, colIndex - 1, maxRowIndex, maxColIndex)) {
                indexes[2] = new int[]{rowIndex, colIndex - 1};
            } else {
                indexes[2] = new int[]{rowIndex, maxColIndex - 1};
            }

            if (indexExists(rowIndex, colIndex + 1, maxRowIndex, maxColIndex)) {
                indexes[3] = new int[]{rowIndex, colIndex + 1};
            } else {
                indexes[3] = new int[]{rowIndex, 0};
            }

            return indexes;
        }

        private static boolean indexExists(int row, int col, int maxRowIndex, int maxColIndex) {
            return row >= 0 && col >= 0 && row < maxRowIndex && col < maxColIndex;
        }
    }

在此代码段中,

if (!visitedElements[node.rowIndex][node.colIndex] && matrix[row][col] == matrix[node.rowIndex][node.colIndex]) {
    visitedElements[row][col] = true;
    counter++;
    stack.push(node);
}

你正在做 visitedElements[row][col] = true; 这实际上是使当前索引本身再次为真。所以,它的邻居从来没有机会成为 true 并且一直在互相添加。因此,它超过了时间限制(因为您的代码看起来很准确)。

visitedElements[row][col] = true;更改为visitedElements[node.rowIndex][node.colIndex] = true;