Leetcode Day6 (图论I, dfs, bfs)

创建一个visited的模版

# m x n大小的矩阵
m = len(matrix)
n = len(matrix[0])
visited = [[False for _ in range(n)] for _ in range(m)]
for i in range(m):
	for j in range(n):
	blablabla
# DFS 模版
```python

200 岛屿数量

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        n = len(grid)
        m = len(grid[0])
        res = 0
        visited = [[False for _ in range(m)] for _ in range(n)]
        
        def dfs(x, y):
            if x < 0 or x >= n or y < 0 or y >= m or visited[x][y] or grid[x][y] == '0':
                return
            visited[x][y] = True
            dfs(x-1, y)
            dfs(x+1, y)
            dfs(x, y-1)
            dfs(x, y+1)

        for i in range(n):
            for j in range(m):
                if grid[i][j] == '1' and not visited[i][j]:
                    res += 1
                    dfs(i, j)

        return res

主要的地方是res在哪里加, dfs的直接返回情况有哪些(一定要注意or grid[x][y] == ‘0’)

695 岛屿的最大面积

这个地方的区别就在于在哪里进行面积+=1的操作, 实际上本方法用的是递归

return 1 + dfs(x-1, y) + dfs(x+1, y) + dfs(x, y-1) + dfs(x, y+1)
class Solution:
    def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
        n = len(grid)
        m = len(grid[0])
        visited = [[False for _ in range(m)] for _ in range(n)]
        
        def dfs(x, y):
            if x < 0 or x >= n or y < 0 or y >= m or visited[x][y] or grid[x][y] == 0:
                return 0 
            visited[x][y] = True
            return 1 + dfs(x-1, y) + dfs(x+1, y) + dfs(x, y-1) + dfs(x, y+1)
        
        res = 0
        for i in range(n):
            for j in range(m):
                if grid[i][j] == 1 and not visited[i][j]:
                    res = max(res, dfs(i, j))

        return res

当然不这样递归也可以, 但就需要对每一个递归开始初始化一个global variable

def dfs(grid, visited, x, y):
    """
    深度优先搜索,对一整块陆地进行标记
    """
    global count  # 定义全局变量,便于传递count值
    for i, j in position:
        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)

463 岛屿的周长

class Solution:
    def islandPerimeter(self, grid: List[List[int]]) -> int:
        m, n = len(grid), len(grid[0])
        
        def dfs(i, j):
            if i < 0 or j < 0 or i >= m or j >= n or grid[i][j] == 0:
                return 1
            if grid[i][j] == 2:  # 已访问
                return 0
            
            grid[i][j] = 2  # 标记为已访问
            
            return (dfs(i-1, j) +
                    dfs(i+1, j) +
                    dfs(i, j-1) +
                    dfs(i, j+1))
        
        total_perimeter = 0
        for i in range(m):
            for j in range(n):
                if grid[i][j] == 1:
                    total_perimeter += dfs(i, j)
        
        return total_perimeter

虽然写的是easy但一点都不easy好吧, 什么时候多加1呢? 当dfs每经过一个水域或者边界的时候, 就会增加1

994 腐烂的橘子

class Solution:
    def orangesRotting(self, grid: List[List[int]]) -> int:
        R, C = len(grid), len(grid[0])

        # queue - all starting cells with rotting oranges
        queue = collections.deque()
        for r, row in enumerate(grid):
            for c, val in enumerate(row):
                if val == 2:
                    queue.append((r, c, 0))

        def neighbors(r, c) -> (int, int):
            for nr, nc in ((r - 1, c), (r, c - 1), (r + 1, c), (r, c + 1)):
                if 0 <= nr < R and 0 <= nc < C:
                    yield nr, nc

        d = 0
        while queue:
            r, c, d = queue.popleft()
            for nr, nc in neighbors(r, c):
                if grid[nr][nc] == 1:
                    grid[nr][nc] = 2
                    queue.append((nr, nc, d + 1))

        if any(1 in row for row in grid):
            return -1
        return d
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值