[Leetcode] [Tutorial] Graph theory


200. Number of islands

You are given a two-dimensional grid consisting of '1' (land) and '0' (water). Please count the number of islands in the grid.

Islands are always surrounded by water, and each island can only be formed by connecting horizontally and/or vertically adjacent land masses.

Additionally, you can assume that all four sides of the grid are surrounded by water.

Example 1:
Input: grid = [
["1","1","1","1","0"], [
"1","1","0","1","0" ],
["1","1","0","0","0"], [
"0","0","0","0","0"] ]
Output
: 1

Example 2:
Input: grid = [
["1","1","0","0","0"], [
"1","1","0","0","0" ],
["0","0","1","0","0"], [
"0","0","0","1","1"] ]
Output
: 3

Solution

Generally speaking, a reasonable approach is to traverse the entire two-dimensional grid. Whenever we encounter a 1, we perform a depth-first search or breadth-first search on it, and mark all adjacent 1s searched as Visited. We then continue traversing the rest of the grid, and every time we encounter a new unvisited 1, we know we've found a new island.

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        m, n = len(grid), len(grid[0])
        count = 0

        def dfs(x, y):
            # 如果坐标超出边界或者该位置不是陆地(已经被访问过或者本来就是水),则结束当前递归
            if x < 0 or x >= m or y < 0 or y >= n or grid[x][y] == '0':
                return
            grid[x][y] = '0'
            dfs(x - 1, y)
            dfs(x + 1, y)
            dfs(x, y - 1)
            dfs(x, y + 1)

        # 遍历所有单元格,当发现陆地时,进行深度优先搜索,并将岛屿数量加1
        for i in range(m):
            for j in range(n):
                if grid[i][j] == '1':
                    count += 1
                    dfs(i, j)
        return count

Depth-first search can also be implemented directly in the main function.

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        # 定义上下左右四个方向
        directions = [(0, 1), (0, -1), (-1, 0), (1, 0)]

        m, n = len(grid), len(grid[0])
        count = 0

        # 遍历所有单元格,当发现陆地时,进行深度优先搜索,并将岛屿数量加1
        for i in range(m):
            for j in range(n):
                if grid[i][j] == '1':
                    # 将访问过的陆地变为水
                    grid[i][j] = '0'
                    count += 1
                    # 使用栈进行深度优先搜索
                    stack = [(i, j)]
                    while stack:
                        cur_i, cur_j = stack.pop()
                        for di, dj in directions:
                            ni, nj = cur_i + di, cur_j + dj
                            if 0 <= ni < m and 0 <= nj < n and grid[ni][nj] == '1':
                                # 将访问过的陆地变为水
                                grid[ni][nj] = '0'
                                stack.append((ni, nj))
        return count

Breadth-first search is also a possible solution.

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        # 定义上下左右四个方向
        directions = [(0, 1), (0, -1), (-1, 0), (1, 0)]

        m, n = len(grid), len(grid[0])
        count = 0

        def bfs(i, j):
            # 使用队列进行广度优先搜索
            queue = deque([(i, j)])
            while queue:
                i, j = queue.popleft()
                for di, dj in directions:
                    ni, nj = i + di, j + dj
                    if 0 <= ni < m and 0 <= nj < n and grid[ni][nj] == '1':
                        # 将访问过的陆地变为水
                        grid[ni][nj] = '0'
                        queue.append((ni, nj))

        # 遍历所有单元格,当发现陆地时,进行广度优先搜索,并将岛屿数量加1
        for i in range(m):
            for j in range(n):
                if grid[i][j] == '1':
                    # 将访问过的陆地变为水
                    grid[i][j] = '0'
                    bfs(i, j)
                    count += 1

        return count

994. Rotten Oranges

In a given mxn grid, each cell can have one of three values:

A value of 0 represents an empty cell;
a value of 1 represents a fresh orange;
a value of 2 represents a rotten orange.
Every minute, the fresh oranges adjacent to the rotten orange in 4 directions will rot.

Returns the minimum number of minutes that must elapse until there are no more fresh oranges in the cell. If not possible, returns -1.

Example 1:

Input: grid = [[2,1,1],[1,1,0],[0,1,1]]
Output: 4

Solution

This problem is actually a classic breadth-first search problem, because we want to know how long it will take for a rotten orange to rot all the fresh oranges. We can start with all rotten oranges, rot their adjacent fresh oranges, and add one to the rot time until no new oranges are rotten. If there are still fresh oranges at the end, then return -1, otherwise return the maximum decay time - 1.

class Solution:
    def orangesRotting(self, grid: List[List[int]]) -> int:
        # 定义上下左右四个方向
        directions = [(0, 1), (0, -1), (-1, 0), (1, 0)]

        m, n = len(grid), len(grid[0])

        queue = deque()
        fresh = 0

        # 将所有腐烂的橘子加入队列,并计算新鲜橘子的数量
        for i in range(m):
            for j in range(n):
                if grid[i][j] == 2:
                    queue.append((i, j, 0))  # i, j 为坐标,0 为腐烂时间
                elif grid[i][j] == 1:
                    fresh += 1

        if fresh == 0:  # 如果没有新鲜橘子,直接返回0
            return 0

        while queue:
            i, j, t = queue.popleft()
            for di, dj in directions:
                ni, nj = i + di, j + dj
                if 0 <= ni < m and 0 <= nj < n and grid[ni][nj] == 1:
                    grid[ni][nj] = 2
                    fresh -= 1
                    queue.append((ni, nj, t + 1))

        # 如果仍然有新鲜橘子,返回-1
        if fresh > 0:
            return -1

        # 否则,返回最后一个腐烂的橘子的时间
        return t

Guess you like

Origin blog.csdn.net/weixin_45427144/article/details/131641764