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

99.岛屿数量(深搜):

文章链接
题目链接;99.岛屿数量

思路:

分析题目可知要求的是岛屿的数量,实际思路只需要先遍历一遍矩阵,遍历过程中,让节点用深搜或者广搜给能接触到的陆地都标记上,那么当深搜/广搜结束,再遍历到没有标记过的节点时,说明是新陆地,计数器加1。

深搜代码1
dp = [[1, 0], [0, 1], [-1, 0], [0, -1]]		# 节点的上下左右位置
def dfs(grid, visited, x, y):
    for i in range(4):
        nextx = x + dp[i][0]
        nexty = y + dp[i][1]
        if nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]):   # 越界
            continue
        if not visited[nextx][nexty] and grid[nextx][nexty]:	# 是没有访问过的陆地节点
            visited[nextx][nexty] = True
            dfs(grid, visited, nextx, nexty)
             
def main():
    n, m = map(int, input().split())
    grid = []
    for _ in range(n):
        grid.append(list(map(int, input().split())))
     
    result = 0  # 记录陆地数目
    visited = [[False] * m for _ in range(n)]
    for x in range(n):
        for y in range(m):
            if not visited[x][y] and grid[x][y]:
                visited[x][y] = True    # 这里要记得设置为True
                result += 1     # 找到了新的陆地
                dfs(grid, visited, x, y)
    print(result)
     
if __name__ == '__main__':
    main()
深搜代码2
dp = [[1, 0], [0, 1], [-1, 0], [0, -1]]
def dfs(grid, visited, x, y):
    if visited[x][y] or grid[x][y] == 0:    # 访问过/海水
        return 
    visited[x][y] = True
    for i in range(4):
        nextx = x + dp[i][0]
        nexty = y + dp[i][1]
        if nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]):   # 越界
            continue
        #if not visited[nextx][nexty] and grid[nextx][nexty]:
        #    visited[nextx][nexty] = True
        dfs(grid, visited, nextx, nexty)
            
def main():
    n, m = map(int, input().split())
    grid = []
    for _ in range(n):
        grid.append(list(map(int, input().split())))
    
    result = 0  # 记录陆地数目
    visited = [[False] * m for _ in range(n)]
    for x in range(n):
        for y in range(m):
            if not visited[x][y] and grid[x][y]:
                # visited[x][y] = True    # 这里要记得设置为True
                result += 1     # 找到了新的陆地
                dfs(grid, visited, x, y)
    print(result)
    
if __name__ == '__main__':
    main()
    

代码1和代码2的区别在于,代码1调用dfs的条件判断放在了代码2的边界条件位置。
代码1的写法是: 当前节点是否合法已经判断完了,visited设置为True已经在上一个dfs中设置了;而进入下一个dfs的节点,其是否合法已经在调用dfs前判断完了
代码2的写法是: 只要节点不越界,就调用dfs,至于合法判断,在dfs的临界条件处判断,visited设置在合法判断之后设置


99.岛屿数量(广搜):

文章链接
题目链接:99.岛屿数量

思路:

本题就是上一题,只是深搜换成广搜,一般用队列完成广搜,此处广搜也有两种,1是先判断节点是否合法,合法再设置visited和加入队列;2是先把节点加入队列,出队列时再判断是否合法和设置visited。
2会导致一个问题,会出现节点重复入队的情况,如下图
在这里插入图片描述
因此只采用1,即先判断节点是否合法,再设置visited和入队

from collections import deque
direction = [[1, 0], [0, 1], [-1, 0], [0, -1]]
def bfs(grid, visited, x, y):
    que = deque()
    que.append([x, y])
    while len(que) != 0:
        curx, cury = que.popleft()
        for i in range(4):
            nextx, nexty = curx + direction[i][0], cury + direction[i][1]
            if nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]):   # 越界
                continue
            if not visited[nextx][nexty] and grid[nextx][nexty]:
                visited[nextx][nexty] = True
                que.append([nextx, nexty])

def main():
    n, m = map(int, input().split())
    grid = []
    for _ in range(n):
        grid.append(list(map(int, input().split())))
    visited = [[False] * m for _ in range(n)]
    result = 0  # 记录陆地数
    for x in range(n):
        for y in range(m):
            if not visited[x][y] and grid[x][y]:
                visited[x][y] = True
                result += 1
                bfs(grid, visited, x, y)
    print(result)
if __name__ == '__main__':
    main()
        

100.岛屿的最大面积:

文章链接
题目链接:岛屿的最大面积

深搜

深搜的话,使用全局变量content记录当前陆地的面积。然后还是深搜的两种方法
1 dfs处理下一个节点,判断节点是否合法,合法则设置visited和进入下一节dfs,同时content岛屿面积 + 1
2 dfs处理当前节点,首先判断当前节点是否合法,合法的话设置visited数组,content岛屿面积 + 1,再判断周围节点
以1为例

direction = [[1, 0], [0, 1], [-1, 0], [0, -1]]
content = 0
def dfs(grid, visited, x, y):
    global content
    # print('v: ' + str(content) + 'x: ' + str(x) + 'y: ' + str(y))
    for i in range(4):
        nextx, nexty = x + direction[i][0], y + direction[i][1]
        if nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]):   # 越界
            continue
        if not visited[nextx][nexty] and grid[nextx][nexty]:
            visited[nextx][nexty] = True
            content += 1
            dfs(grid, visited, nextx, nexty)
 
def main():
    global content
    n, m = map(int, input().split())
    grid = []
    for _ in range(n):
        grid.append(list(map(int, input().split())))
     
    result = 0
    visited = [[False] * m for _ in range(n)]
    for x in range(n):
        for y in range(m):
            if not visited[x][y] and grid[x][y]:
                visited[x][y] = 1
                content = 1   # 陆地面积
                dfs(grid, visited, x, y)
                #print('v: ' + str(content))
                if content > result:  # 记录最大的陆地面积
                    result = content
    print(result)
     
if __name__ == '__main__':
    main()
广搜

还是上一题广搜的思路,使用队列进行广度优先搜索,先判断节点是否合法,再设置visited和入队。
要记录陆地面积的话,在函数中设置content,且初始化为2,广搜过程中,入队一个位置,content+1,最后返回content

from collections import deque
direction = [[1, 0], [0, 1], [-1, 0], [0, -1]]
def bfs(grid, visited, x, y):
    que = deque()
    que.append([x, y])
    content = 1 # 记录陆地面积
    while len(que) != 0:
        curx, cury = que.popleft()
        for i in range(4):
            nextx, nexty = curx + direction[i][0], cury + direction[i][1]
            if nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]):   # 越界
                continue
            if not visited[nextx][nexty] and grid[nextx][nexty]:
                visited[nextx][nexty] = True
                content += 1
                que.append([nextx, nexty])
    return content
def main():
    n, m = map(int, input().split())
    grid = []
    for _ in range(n):
        grid.append(list(map(int, input().split())))
    result = 0
    visited = [[False] * m for _ in range(n)]
    for x in range(n):
        for y in range(m):
            if not visited[x][y] and grid[x][y]:
                visited[x][y] = True
                content = bfs(grid, visited, x, y)
                result = max(result, content)
    print(result)
if __name__ == '__main__':
    main()

学习收获:

  • 首先知道了在一张地图上进行广搜和深搜,然后利用广搜和深搜标记遍历过的陆地,当广搜/深搜结束后, 如果还遇到没有标记过的陆地,那么就是岛屿数量 + 1
  • 而岛屿面积还是在这张地图上进行处理,在广搜和深搜的代码上改进即可;深搜(添加全局变量content记录岛屿面积),广搜(函数内添加变量content记录岛屿面积)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值