Skip to main content
deleted 3 characters in body
Source Link

The time complexity for this algorithm is O(nm), but it comes at an added space complexity cost of O(nm), due to the BFS queue growing withgrowth on the regular BFS algorithm and the added DFS items

The time complexity for this algorithm is O(nm), but it comes at an added space complexity cost of O(nm), due to the BFS queue growing with the regular BFS algorithm and the added DFS items

The time complexity for this algorithm is O(nm), but it comes at an added space complexity cost of O(nm), due to the BFS queue growth on the regular BFS algorithm and the added DFS items

Source Link

As an alternative, I will suggest a solution that instead of iterating through all of the grid's nodes in search of a component that was not visited in the main loop, it avoids visiting a visited node in this loop via a modified BFS.

The gist of this algorithm is to perform an explorative BFS, which triggers a DFS (like your algorithm) to measure the size of the group.

Difference being that during the DFS step, it adds empty (non-visited) slots to the BFS queue, thus avoiding the need to re-check the component group.

The time complexity for this algorithm is O(nm), but it comes at an added space complexity cost of O(nm), due to the BFS queue growing with the regular BFS algorithm and the added DFS items

from collections import deque

EMPTY = 0
FILLED = 1
VISITED = 2


def largest_connected_component(grid):
    
    def is_valid(x, y):
        return (0 <= x < len(grid) and 0 <= y < len(grid[0]) and
                grid[x][y] != VISITED)

    def traverse_component(x, y):
        grid[x][y] = VISITED
        result = 1
        for adjacent in ((x + 1, y),
                         (x - 1, y),
                         (x, y + 1),
                         (x, y - 1)):
            if (is_valid(*adjacent)):
                if (grid[adjacent[0]][adjacent[1]] == EMPTY):
                    q.append(adjacent)
                    grid[adjacent[0]][adjacent[1]] = VISITED
                else:
                    result += traverse_component(*adjacent)

        return result

    max_filled_size = 0
    q = deque()

    if (grid[0][0] == EMPTY):
        q.append((0, 0))
        grid[0][0] = VISITED
    else:
        max_filled_size = max(max_filled_size, traverse_component(0, 0))

    while q:
        x, y = q.popleft()

        for adjacent in ((x + 1, y),
                         (x - 1, y),
                         (x, y + 1),
                         (x, y - 1)):
            if (is_valid(*adjacent)):
                if (grid[adjacent[0]][adjacent[1]] == EMPTY):
                    q.append(adjacent)
                    grid[adjacent[0]][adjacent[1]] = VISITED
                else:  # FILLED
                    max_filled_size = max(max_filled_size, traverse_component(*adjacent))

    return max_filled_size

# Examples
print(largest_connected_component([[0, 1, 0], [1, 0, 1], [0, 1, 1]]))
print(largest_connected_component([[1, 1, 1], [0, 1, 0], [1, 0, 1]]))
print(largest_connected_component([[1, 0, 0, 1, 1, 1, 1, 0],
                                   [1, 0, 1, 0, 0, 0, 0, 1],
                                   [1, 0, 1, 0, 0, 1, 0, 1],
                                   [1, 0, 0, 0, 1, 0, 1, 0],
                                   [0, 0, 0, 0, 1, 1, 1, 0],
                                   [1, 0, 1, 1, 0, 0, 1, 0],
                                   ]))