数据结构与算法-二维平面上使用回溯法

在二维平面上使用回溯算法

79. 单词搜索(中等)

79. 单词搜索
在这里插入图片描述
在这里插入图片描述

DFS 和状态重置

class Solution:
    steps = [(0,1),(0,-1),(1,0),(-1,0)]
    def exist(self, board: List[List[str]], word: str) -> bool:
        if not board or not board[0]:
            return False
        
        rows = len(board)
        cols = len(board[0])
        visited = [[0 for _ in range(cols)] for _ in range(rows)]

        for i in range(rows):
            for j in range(cols):
                if board[i][j]==word[0] and visited[i][j]==0:
                    visited[i][j]=1
                    if self.dfs(board,visited,word[1:],i,j):
                        return True
                    visited[i][j]=0
        return False

    def dfs(self,board,visited,word,i,j):
        if not word:
            return True

        for step in self.steps:
            x = i+step[0]
            y = j+step[1]
            if x>=0 and x<len(board) and y>=0 and y<len(board[0]) \
                    and board[x][y]==word[0] and visited[x][y]==0:
                visited[x][y] = 1
                if self.dfs(board,visited,word[1:],x,y):
                    return True
                visited[x][y] = 0
        return False

Floodfill,一类经典问题

200. 岛屿数量(中等)

200. 岛屿数量
在这里插入图片描述
方法一:DFS

class Solution:
    steps = [(0,1),(0,-1),(1,0),(-1,0)]
    def numIslands(self, grid: List[List[str]]) -> int:
        if not grid or not grid[0]:
            return 0
        
        rows = len(grid)
        cols = len(grid[0])
        visited = [[0 for _ in range(cols)] for _ in range(rows)]

        res = 0
        for i in range(rows):
            for j in range(cols):
                if grid[i][j]=='1' and visited[i][j]==0:
                    visited[i][j]=1
                    res += 1
                    self.dfs(grid,visited,i,j)
        return res
    
    def dfs(self,grid,visited,i,j):

        for step in self.steps:
            x = i+step[0]
            y = j+step[1]
            if x>=0 and x<len(grid) and y>=0 and y<len(grid[0]) \
                    and grid[x][y]=='1' and visited[x][y]==0:
                visited[x][y] = 1
                self.dfs(grid,visited,x,y)
        return

已经访问过的格子不能再访问一次,与79的区别

复杂度分析
时间复杂度:O(MN),其中 M 和 N 分别为行数和列数。
空间复杂度:O(MN),在最坏情况下,整个网格均为陆地,深度优先搜索的深度达到 M*N。

方法二:BFS
BFS搭配辅助队列
加入队列即标记为已读

class Solution:
    
    def numIslands(self, grid: List[List[str]]) -> int:
        if not grid or not grid[0]:
            return 0
        
        rows = len(grid)
        cols = len(grid[0])
        visited = [[0 for _ in range(cols)] for _ in range(rows)]
        queue = []
        res = 0
        steps = [(0,1),(0,-1),(1,0),(-1,0)]
  
        for i in range(rows):
            for j in range(cols):
                if grid[i][j]=='1' and visited[i][j]==0:
                    queue.append((i,j))
                    visited[i][j] = 1
                    res += 1
                    while queue:
                        x,y = queue.pop(0)
                        for step in steps:
                            x1 = x+step[0]
                            y1 = y+step[1]
                            if x1>=0 and x1<rows and y1>=0 and y1<cols \
                                     and grid[x1][y1]=='1' and visited[x1][y1]==0:
                                queue.append((x1,y1))
                                visited[x1][y1] = 1
        return res

复杂度分析
时间复杂度:O(MN),其中 M 和 N 分别为行数和列数。
空间复杂度:O(MN),visited数组M*N;在最坏情况下,整个网格均为陆地,队列的大小可以达到min(M,N)。

方法三:并查集
TODO

参考题解区大神

130. 被围绕的区域(中等)

130. 被围绕的区域
在这里插入图片描述
思路:
边界上的’O’或与边界上的’O’相连的’O’不会被填充,因此先找出这些’O’,赋值为’#‘以区分。
把剩下的’O’填充为’X’,把’#‘还原为’O’。

BFS

class Solution:
    def solve(self, board: List[List[str]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        if not board or not board[0]:
            return
        rows = len(board)
        cols = len(board[0])
        queue = []
        steps = [(0,1),(0,-1),(1,0),(-1,0)]

        for i in range(rows):
            for j in range(cols):
                if (i==0 or i==rows-1 or j==0 or j==cols-1) and board[i][j]=='O':
                    board[i][j]='#'
                    queue.append((i,j))
                    while queue:
                        x,y = queue.pop(0)
                        for step in steps:
                            x1 = x+step[0]
                            y1 = y+step[1]
                            if x1>=0 and x1<rows and y1>=0 and y1<cols and board[x1][y1]=='O':
                                board[x1][y1]='#'
                                queue.append((x1,y1))
        for i in range(rows):
            for j in range(cols):
                if board[i][j]=='O':
                    board[i][j]='X'
                elif board[i][j]=='#':
                    board[i][j]='O'
        return

复杂度分析
时间复杂度:O(MN)
空间复杂度:广度优先搜索队列的开销

417. 太平洋大西洋水流问题

417. 太平洋大西洋水流问题
在这里插入图片描述
在这里插入图片描述
思路
从边缘向中间;
分别计算太平洋和大西洋可达的单元;
求交集。

class Solution:
    steps = [(0,1),(0,-1),(1,0),(-1,0)]
    def pacificAtlantic(self, matrix: List[List[int]]) -> List[List[int]]:
        if not matrix or not matrix[0]:
            return []
        
        rows = len(matrix)
        cols = len(matrix[0])

        res1 = set()#太平洋
        res2 = set()#大西洋
        
        for i in range(rows):
            self.dfs(matrix,res1,i,0)
            self.dfs(matrix,res2,i,cols-1)
        
        for j in range(cols):
            self.dfs(matrix,res1,0,j)
            self.dfs(matrix,res2,rows-1,j)
        
        return res1&res2#set求交集

    def dfs(self,matrix,res,i,j):
        res.add((i,j))
        for step in self.steps:
            x = i+step[0]
            y = j+step[1]
            if x>=0 and x<len(matrix) and y>=0 and y<len(matrix[0]) \
               and matrix[x][y]>=matrix[i][j] and (x,y) not in res:
                self.dfs(matrix,res,x,y)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值