简体   繁体   English

试图理解为什么使用 BFS 搜索网格的空间复杂度是 O(m * n),其中 m 不是。 行数,n 为否。 列数

[英]Trying to understand why the Space Complexity of searching through a grid using BFS is O(m * n), where m is no. of rows and n is no. of cols

I am trying to understand the space complexity of using BFS in a grid.我试图了解在网格中使用 BFS 的空间复杂性。 When we start on a cell in a grid of m * n dimensions, we could go either up, right, down and left.当我们从 m * n 维网格中的一个单元格开始时,我们可以向上、向右、向下和向左 go。

My understanding is the Space Complexity should be O(m + n) if we start somewhere in the middle.我的理解是,如果我们从中间的某个地方开始,空间复杂度应该是 O(m + n)。 If we start in one of the 4 corners it should be O(min(m, n)).如果我们从 4 个角之一开始,它应该是 O(min(m, n))。 So overall it could be O(m + n) in the worst case given we don't know where to start.所以总的来说,考虑到我们不知道从哪里开始,在最坏的情况下它可能是 O(m + n)。

I tried to test on my local by starting on all of the cells individually in a grid and calculate the max size of the queue and understand the Space Complexity.我尝试通过在网格中单独启动所有单元格并计算队列的最大大小并了解空间复杂度来在本地进行测试。

My test code:我的测试代码:

class Solution {

    int max = 0;

    public static void main(String[] args) {
        Solution solution = new Solution();

        int rows = 200, cols = 200;
        int[][] grid = new int[rows][cols];

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                solution.initializeGrid(grid, rows, cols);
                solution.processGrid(grid, rows, cols, i, j);
            }
        }

        System.out.println("Highest queue size is " + solution.max);
    }

    private void initializeGrid(int[][] grid, int rows, int cols) {
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                grid[i][j] = 1;
            }
        }
    }

    private void processGrid(int[][] grid, int rows, int cols, int row, int col) {
        Queue<int[]> queue = new LinkedList<>();
        int[] childrenRows = new int[]{-1, 0, 1, 0};
        int[] childrenCols = new int[]{0, 1, 0, -1};

        queue.add(new int[]{row, col});
        grid[row][col] = 0;

        while (!queue.isEmpty()) {
            max = Math.max(max, queue.size());

            int[] parent = queue.poll();
            int pr = parent[0], pc = parent[1];

            for (int i = 0; i < 4; i++) {
                int cr = pr + childrenRows[i], cc = pc + childrenCols[i];

                if (cr >= 0 && cr < rows && cc >= 0 && cc < cols && grid[cr][cc] == 1) {
                    queue.add(new int[]{cr, cc});
                    grid[cr][cc] = 0;
                }
            }
        }
    }
}

The output for the given input of m = 200, n = 200 is给定输入 m = 200, n = 200 的 output 是

The highest queue size is 399. This value proportional to O(m + n)

I know this is not the right way to calculate Space Complexity but I want to the know exact space used by the queue and if it's proportional to O(m * n) or not.我知道这不是计算空间复杂度的正确方法,但我想知道队列使用的确切空间以及它是否与 O(m * n) 成正比。

I tried with other larger inputs.我尝试了其他更大的输入。 Still, the Space Complexity is O(m + n).尽管如此,空间复杂度仍然是 O(m + n)。

Am I missing something here?我在这里错过了什么吗? Could someone please help me to understand the logic?有人可以帮我理解逻辑吗?

You are focusing on the max queue size, but you hit the O(m * n) space right at the beginning of your algorithm:您正在关注最大队列大小,但您在算法开始时就达到了O(m * n)空间:

boolean[][] visited = new boolean[rows][cols]

You've just allocated O(m * n) space!您刚刚分配了O(m * n)空间!

In generic BFS, you have to keep track of all visited states, so the space bound cannot be lower than the total number of states.在通用 BFS 中,您必须跟踪所有访问过的状态,因此空间限制不能低于状态总数。


That being said O(m * n) is only valid when the grid can be complex.也就是说O(m * n)仅在网格可能很复杂时才有效。 If it's just a full grid of size mxn, you can optimize the algorithm to make it O(m + n) space -- you don't need to keep the whole history of visited cells in memory.如果它只是一个大小为 mxn 的完整网格,您可以优化算法以使其成为O(m + n)空间——您不需要在 memory 中保留访问单元格的整个历史记录。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM