Bootstrap

代码随想录算法训练营第五十一天|KM99.岛屿数量(深度搜索版)|KM99.岛屿数量(广度搜索版)|KM100.岛屿的最大面积

99. 岛屿数量(深度搜索版)

1、方法一

# 代表四个方向:上、右、下、左
direction = [[0, 1], [1, 0], [0, -1], [-1, 0]]

def dfs(grid, visited, x, y):
    '''
    对一块陆地进行深度优先遍历并标记
    :param grid:矩阵
    :param visited:访问过程
    :param x:x方向
    :param y:y方向
    :return:
    '''
    for i, j in direction:
        next_x = x + i
        next_y = y + j
        # 下标越界,跳过
        if next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]):
            continue
        if not visited[next_x][next_y] and grid[next_x][next_y] == 1:
            visited[next_x][next_y] = True
            dfs(grid, visited, next_x, next_y)

if __name__ == '__main__':
    # 版本一
    n, m = map(int, input().split())
    # 邻接矩阵
    grid = []
    for i in range(n):
        grid.append(list(map(int, input().split())))
    print(grid[0])
    # 访问表
    visited = [[False]*m for _ in range(n)]
    res = 0
    for i in range(n):
        for j in range(m):
            # 判断:如果当前节点是陆地,res+1并标记访问该结点,使用深度搜索标记相邻陆地。
            if grid[i][j] == 1 and not visited[i][j]:
                # 遇到没访问过的陆地,+1
                res += 1
                visited[i][j] = True
                dfs(grid, visited, i, j)
    print(res)

2、方法二

# 代表四个方向:上、右、下、左
direction = [[0, 1], [1, 0], [0, -1], [-1, 0]]

def dfs(grid, visited, x, y):
    '''
    对一块陆地进行深度优先遍历并标记
    :param grid:矩阵
    :param visited:访问过程
    :param x:x方向
    :param y:y方向
    :return:
    '''
    # 与版本一的差别,在调用前增加判断终止条件(访问过的节点或者遇到海水)
    if visited[x][y] or grid[x][y] == 0:
        return
    # 标记访问过
    visited[x][y] = True
    for i, j in direction:
        next_x = x + i
        next_y = y + j
        # 下标越界,跳过
        if next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]):
            continue
        dfs(grid, visited, next_x, next_y)

if __name__ == '__main__':
    # 版本二
    n, m = map(int, input().split())
    # 邻接矩阵
    grid = []
    for i in range(n):
        grid.append(list(map(int, input().split())))
    print(grid[0])
    # 访问表
    visited = [[False]*m for _ in range(n)]
    res = 0
    for i in range(n):
        for j in range(m):
            # 判断:如果当前节点是陆地,res+1并标记访问该结点,使用深度搜索标记相邻陆地。
            if grid[i][j] == 1 and not visited[i][j]:
                # 遇到没访问过的陆地,+1
                res += 1
                dfs(grid, visited, i, j)
    print(res)

99. 岛屿数量(广度搜索版)

        用广搜做这道题目的时候存在超时,可能忽略其中一个重要细节,根本原因在于只要 加入队列就代表 走过,就需要标记,而不是从队列拿出来的时候再去标记走过;

        如下图所示:

from collections import deque
# 代表四个方向:上、右、下、左
directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]

def bfs(grid, visited, x, y):
    '''
    对一块陆地进行深度优先遍历并标记
    :param grid:矩阵
    :param visited:访问过程
    :param x:x方向
    :param y:y方向
    :return:
    '''
    que = deque([])
    que.append([x, y])
    while que:
        cur_x, cur_y = que.popleft()
        for i, j in directions:
            next_x = cur_x + i
            next_y = cur_y + j
            # 下标越界,跳过
            if next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]):
                continue
            if not visited[next_x][next_y] and grid[next_x][next_y] == 1:
                visited[next_x][next_y] = True
                que.append([next_x, next_y])

def main():
    n, m = map(int, input().split())
    # 邻接矩阵
    grid = []
    for i in range(n):
        grid.append(list(map(int, input().split())))
    # 访问表
    visited = [[False] * m for _ in range(n)]
    res = 0
    for i in range(n):
        for j in range(m):
            # 判断:如果当前节点是陆地,res+1并标记访问该结点,使用深度搜索标记相邻陆地。
            if grid[i][j] == 1 and not visited[i][j]:
                # 遇到没访问过的陆地,+1
                res += 1
                bfs(grid, visited, i, j)
    print(res)

if __name__ == '__main__':
    main()

100. 岛屿的最大面积

        本题是 dfs,bfs基础类题目,就是搜索每个岛屿上“1”的数量,然后取一个最大的。

1、dfs方法

# 代表四个方向:上、右、下、左
directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]
count = 0

def dfs(grid, visited, x, y):
    """
    深度优先搜索,对一整块陆地进行标记
    """
    global count  # 定义全局变量,便于传递count值
    for i, j in directions:
        cur_x = x + i
        cur_y = y + j
        # 下标越界,跳过
        if cur_x < 0 or cur_x >= len(grid) or cur_y < 0 or cur_y >= len(grid[0]):
            continue
        if not visited[cur_x][cur_y] and grid[cur_x][cur_y] == 1:
            visited[cur_x][cur_y] = True
            count += 1
            dfs(grid, visited, cur_x, cur_y)

def main():
    global count
    n, m = map(int, input().split())
    # 邻接矩阵
    grid = []
    for i in range(n):
        grid.append(list(map(int, input().split())))
    # 访问表
    visited = [[False] * m for _ in range(n)]

    result = 0  # 记录最终结果
    for i in range(n):
        for j in range(m):
            if grid[i][j] == 1 and not visited[i][j]:
                count = 1
                visited[i][j] = True
                dfs(grid, visited, i, j)
                result = max(count, result)

    print(result)

if __name__ == '__main__':
    main()
;