DFS与回溯总结

文章目录

    • 地图类
      • LC200. Number of Islands
      • LC79. Word Search
      • LC1219. 黄金矿工

学习与参考资料:
[1] 2013王道论坛计算机考研机试指南
[2] DFS和BFS讲解及Leetcode刷题小结(1)(JAVA)
[3] DFS和BFS讲解及Leetcode刷题小结(2)(JAVA)

地图类

LC200. Number of Islands

LC200. Number of Islands

DFS与回溯总结_第1张图片

from collections import deque

def dfs(grid,x,y):
    if 0<=x<len(grid) and 0<=y<len(grid[0]) and grid[x][y]=="1":
        grid[x][y]=0  # 将访问之后的陆地变成水,后面便不会再去访问了,省去了记录访问信息的数组
        dfs(grid,x-1,y)
        dfs(grid,x+1,y)
        dfs(grid,x,y-1)
        dfs(grid,x,y+1)

# 也可以用bfs
def bfs(grid, x, y):
    queue = deque()
    queue.append((x, y))
    grid[x][y] = '0'  # 将访问之后的陆地变成水,后面便不会再去访问了,省去了记录访问信息的数组
    while queue:
        directions = [(0,1), (0,-1), (-1,0), (1,0)]
        x, y = queue.popleft()
        for d in directions:
            nx, ny = x + d[0], y + d[1]    
            if 0<=nx<len(grid) and 0<=ny<len(grid[0]) and grid[nx][ny] == '1':
                queue.append((nx, ny))
                grid[nx][ny] = '0'  # 将访问之后的陆地变成水
            
        
class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        if len(grid)==0:
            return 0
        cnt=0
        for x in range(len(grid)):
            for y in range(len(grid[0])):
                if grid[x][y]=="1":
                    # bfs(grid,x,y)
                    dfs(grid,x,y)
                    cnt+=1
        return cnt

LC79. Word Search

题目链接:79. Word Search

DFS与回溯总结_第2张图片

class Solution:
    def dfs(self, board, visited, x, y, word, k):
        """
        整体逻辑是:检查与访问 + 递归与回溯
        1、检查位置合法性与是否已经访问过
        2、访问该位置,如果已经能判断结果则返回
        3、否则,将当前位置设为已访问,对于每个方向的下个位置继续使用dfs
        4、若某个方向成功到达终点则返回结果,若所有方向都失败,则回溯
        """
        # 如果位置不合法或已经访问过
        if not (0 <= x < len(board) and 0 <= y < len(board[0])) or visited[x][y]:
            return False
        if board[x][y] != word[k]:  # 访问当前位置,如果不符合预期,返回False(剪枝)
            return False
        if board[x][y] == word[k] and k == len(word) - 1:  # # 如果该位置符合预期且已经是终点(最后一个单词)
            return True
        visited[x][y] = True  # 递归前先设置当前位置已经访问
        directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
        for d in directions:  # 对每一个方向继续dfs
            nx, ny = x + d[0], y + d[1]
            if self.dfs(board, visited, nx, ny, word, k + 1):  # 递归检查下个位置
                return True  # 如果成功到达终点,则返回True
        # 如果所有方向dfs都失败,则将当前位置设为未访问过,可以让其他方案经过该位置
        visited[x][y] = False
        return False

    def exist(self, board: List[List[str]], word: str) -> bool:
        m = len(board)
        n = len(board[0])
        for x in range(m):
            for y in range(n):
                # 遍历每一个位置,如果符合起点要求则开始使用dfs回溯
                if board[x][y] == word[0]:
                    # 每个起点使用一个全新的visited数组
                    visited = [[False] * n for _ in range(m)]
                    if self.dfs(board, visited, x, y, word, 0):
                        return True
        return False

LC1219. 黄金矿工

1219. 黄金矿工

DFS与回溯总结_第3张图片

class Solution:
    def dfs(self, grid, seen, x, y):
        if not (0 <= x < len(grid) and 0 <= y < len(grid[0])) or grid[x][y] == 0 or (x, y) in seen:
            return 0
        reward = grid[x][y]

        seen.add((x, y))
        max_direction_reward = 0
        for d in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
            nx, ny = x + d[0], y + d[1]
            re = self.dfs(grid, seen, nx, ny)
            if re > max_direction_reward:
                max_direction_reward = re
        seen.remove((x, y))
        return reward + max_direction_reward

    def getMaximumGold(self, grid: List[List[int]]) -> int:
        max_reward = 0
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                reward = self.dfs(grid, set(), i, j)
                if reward > max_reward:
                    max_reward = reward
        return max_reward

你可能感兴趣的:(笔试面试算法题,Interview,Algorithm)