200.Number of Islands

Tags: [BFS], [DFS], [island]

Com: {fb}, {g}

Link: https://leetcode.com/problems/number-of-islands/#/description

Given a 2d grid map of'1's (land) and'0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

Example 1:

11110
11010
11000
00000

Answer: 1

Example 2:

11000
11000
00100
00011

Answer: 3


Better Solution: DFS

class Solution(object):
    def numIslands(self, grid):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        if not grid or not grid[0]:
            return 0

        num_of_rows = len(grid)
        num_of_cols = len(grid[0])

        counter = 0
        for row in xrange(num_of_rows):
            for col in xrange(num_of_cols):
                if grid[row][col] == '1':
                   counter += 1
                   self.dfs(grid, num_of_rows, num_of_cols, row, col)

        return counter

    def dfs(self, grid, num_of_rows, num_of_cols, row, col):
        VISITED_MARK = '100'
        grid[row][col] = VISITED_MARK

        # top
        if row - 1 >= 0 and grid[row - 1][col] == '1':
            self.dfs(grid, num_of_rows, num_of_cols, row - 1, col)

        # left
        if col - 1 >= 0 and grid[row][col - 1] == '1':
            self.dfs(grid, num_of_rows, num_of_cols, row, col - 1)

        # bottom
        if row + 1 < num_of_rows and grid[row + 1][col] == '1':
            self.dfs(grid, num_of_rows, num_of_cols, row + 1, col)

        # right
        if col + 1 < num_of_cols and grid[row][col + 1] == '1':
            self.dfs(grid, num_of_rows, num_of_cols, row, col + 1)

Revelation:

  • Assuming we can modify the grid.

Note:

  • Time complexity = O(num_of_rows * num_of_cols), because each cell we only visited once.

Solution: DFS

class Solution(object):
    def numIslands(self, grid):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        if not grid or not grid[0]:
            return 0

        num_of_rows = len(grid)
        num_of_cols = len(grid[0])

        counter = 0
        visited = [[False for _ in xrange(num_of_cols)] for _ in xrange(num_of_rows)]
        for row in xrange(num_of_rows):
            for col in xrange(num_of_cols):
                if visited[row][col] or grid[row][col] == '0':
                    continue

                # debug:
                print 'debug:[{}][{}]={}, counter={}'.format(row, col, grid[row][col], counter)

                counter += 1
                visited[row][col] = True
                self.dfs(grid, num_of_rows, num_of_cols, row, col, visited)

        return counter

    def dfs(self, grid, num_of_rows, num_of_cols, row, col, visited):
        # check four directions.
        # top
        if row - 1 >= 0 and grid[row - 1][col] == '1' and not visited[row - 1][col]:
            visited[row - 1][col] = True
            self.dfs(grid, num_of_rows, num_of_cols, row - 1, col, visited)

        # left
        if col - 1 >= 0 and grid[row][col - 1] == '1' and not visited[row][col - 1]:
            visited[row][col - 1] = True
            self.dfs(grid, num_of_rows, num_of_cols, row, col - 1, visited)

        # bottom
        if row + 1 < num_of_rows and grid[row + 1][col] == '1' and not visited[row + 1][col]:
            visited[row + 1][col] = True
            self.dfs(grid, num_of_rows, num_of_cols, row + 1, col, visited)

        # right
        if col + 1 < num_of_cols and grid[row][col + 1] == '1' and not visited[row][col + 1]:
            visited[row][col + 1] = True
            self.dfs(grid, num_of_rows, num_of_cols, row, col + 1, visited)

Revelation:

  • The 'label island' approach seems doesn't work.

Note:

  • Time complexity of above solution = O(num_of_rows * num_of_cols), because each cell of the grid, we only visited once.

Time Limited Exceeded: BFS

class Solution(object):
    def numIslands(self, grid):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        if not grid or not grid[0]:
            return 0

        num_of_rows = len(grid)
        num_of_cols = len(grid[0])

        counter = 0
        for row in xrange(num_of_rows):
            for col in xrange(num_of_cols):
                if grid[row][col] == '1':
                   counter += 1
                   self.bfs(grid, num_of_rows, num_of_cols, row, col)

        return counter

    def bfs(self, grid, num_of_rows, num_of_cols, row, col):
        VISITED_MARK = '100'
        queue = collections.deque()
        queue.append((row, col))

        while queue:
            row, col = queue.popleft()
            grid[row][col] = VISITED_MARK

            # top
            if row - 1 >= 0 and grid[row - 1][col] == '1':
                queue.append((row - 1, col))

            # left
            if col - 1 >= 0 and grid[row][col - 1] == '1':
                queue.append((row, col - 1))

            # bottom
            if row + 1 < num_of_rows and grid[row + 1][col] == '1':
                queue.append((row + 1, col))

            # right
            if col + 1 < num_of_cols and grid[row][col + 1] == '1':
                queue.append((row, col + 1))

Revelation:

  • Not sure why BFS is slower than DFS.

Note:

  • Time complexity = O(num_of_rows * num_of_cols), because each cell we only visited once.

results matching ""

    No results matching ""