defdfs(self, grid, visited, x, y): for dx, dy in self.dir: nextx, nexty = x + dx, y + dy if nextx < 0or nextx >= len(grid) or nexty < 0or nexty >= len(grid[0]): continue ifnot visited[nextx][nexty] and grid[nextx][nexty] == "1": visited[nextx][nexty] = True self.dfs(grid, visited, nextx, nexty)
defnumIslands(self, grid: List[List[str]]) -> int: m, n = len(grid), len(grid[0]) res = 0 visited = [[False] * n for _ inrange(m)] for i inrange(m): for j inrange(n): ifnot visited[i][j] and grid[i][j] == "1": visited[i][j] = True self.dfs(grid, visited, i, j) res += 1 return res
defbfs(self, grid, visited, x, y): queue = deque() queue.append((x, y)) visited[x][y] = True while queue: x, y = queue.popleft() for dx, dy in self.dir: nextx, nexty = x + dx, y + dy if ( nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]) ): continue
defnumIslands(self, grid: List[List[str]]) -> int: m, n = len(grid), len(grid[0]) res = 0 visited = [[False] * n for _ inrange(m)] for i inrange(m): for j inrange(n): ifnot visited[i][j] and grid[i][j] == "1": self.bfs(grid, visited, i, j) res += 1 return res
classSolution: defmaxAreaOfIsland(self, grid: List[List[int]]) -> int: m, n = len(grid), len(grid[0]) visited = [[False]*n for _ inrange(m)] dirs = [(-1,0),(0,1),(1,0),(0,-1)] res = 0 tmp = 0 defbfs(grid, i, j, visited): nonlocal tmp nonlocal res tmp+=1 q = deque() q.append((i,j)) visited[i][j] = True while q: x,y = q.popleft() for k in dirs: next_i = x + k[0] next_j = y + k[1] if next_i<0or next_i>=m: continue if next_j<0or next_j>=n: continue if visited[next_i][next_j]: continue if grid[next_i][next_j]==0: continue q.append((next_i,next_j)) visited[next_i][next_j] = True tmp+=1
for i inrange(m): for j inrange(n): ifnot visited[i][j] and grid[i][j]==1: tmp=0 bfs(grid,i,j,visited) res = max(tmp,res) return res
defbfs(self, grid, visited, x, y): queue = deque([(x, y)]) visited[x][y] = True tmp = 1 while queue: x, y = queue.popleft() for dx, dy in self.dir: nextx, nexty = x + dx, y + dy if ( nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]) ): continue if grid[nextx][nexty] == 1andnot visited[nextx][nexty]: queue.append((nextx, nexty)) visited[nextx][nexty] = True tmp += 1 self.max_ = max(self.max_, tmp)
defmaxAreaOfIsland(self, grid: List[List[int]]) -> int: m, n = len(grid), len(grid[0]) visited = [[False] * n for _ inrange(m)] for i inrange(m): for j inrange(n): ifnot visited[i][j] and grid[i][j] == 1: self.bfs(grid, visited, i, j) return self.max_
defdfs(self, grid, visited, x, y): for dx, dy in self.dir: nextx, nexty = x + dx, y + dy if nextx < 0or nextx >= len(grid) or nexty < 0or nexty >= len(grid[0]): continue ifnot visited[nextx][nexty] and grid[nextx][nexty] == 1: visited[nextx][nexty] = True self.dfs(grid, visited, nextx, nexty) self.max_ += 1
defmaxAreaOfIsland(self, grid: List[List[int]]) -> int: m, n = len(grid), len(grid[0]) visited = [[False] * n for _ inrange(m)] res = 0 for i inrange(m): for j inrange(n): ifnot visited[i][j] and grid[i][j] == 1: self.max_ = 1 visited[i][j] = True self.dfs(grid, visited, i, j) res = max(res, self.max_) return res
classSolution: defnumEnclaves(self, grid: List[List[int]]) -> int: # 先从边缘进行遍历,最后统计在中间的岛屿数量 defdfs(i,j): if i<0or i>=m or j<0or j>=n or grid[i][j]==0: return grid[i][j] = 0 dfs(i-1,j) dfs(i+1,j) dfs(i,j-1) dfs(i,j+1) m,n = len(grid),len(grid[0]) for i inrange(m): for j inrange(n): if (i==0or j==0or i==m-1or j==n-1) and grid[i][j]==1: dfs(i,j) res = 0 for i inrange(m): for j inrange(n): if grid[i][j]==1: res+=1 return res
defnumEnclaves(self, grid: List[List[int]]) -> int: # 将四周1改为0 然后遍历中间有多少1 defbfs(x, y): # 修改所有可以联通的地方改成0 queue = deque([(x, y)]) # visited[x][y] = True if grid[x][y] == 1: grid[x][y] = 0 while queue: x, y = queue.popleft() for dx, dy in self.dir: nextx, nexty = x + dx, y + dy if ( nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]) ): continue if grid[nextx][nexty] == 1: queue.append((nextx, nexty)) grid[nextx][nexty] = 0 # visited[nextx][nexty] = True
m, n = len(grid), len(grid[0])
for i inrange(m): for j inrange(n): if grid[i][j] == 1and (i == 0or j == 0or i == m - 1or j == n - 1): bfs(i, j) # print(mygrid) # print(grid) # print(grid) res = 0 for i inrange(m): for j inrange(n): if grid[i][j] == 1: res += 1 return res
defsolve(self, board: List[List[str]]) -> None: """ Do not return anything, modify board in-place instead. """
# 边缘的O都变成A,将其余的O变成X,再将所有的A变成O defdfs(board, x, y): # x y 需要满足边界条件 for dx, dy in self.dir: nextx = x + dx nexty = y + dy if ( nextx < 0 or nextx >= len(board) or nexty < 0 or nexty >= len(board[0]) ): continue if board[nextx][nexty] == "O": board[nextx][nexty] = "A" dfs(board, nextx, nexty)
m, n = len(board), len(board[0])
for i inrange(m): for j inrange(n): if ( i == 0or i == len(board) - 1or j == 0or j == len(board[0]) - 1 ) and board[i][j] == "O": dfs(board, i, j) board[i][j] = "A" # print(board) for i inrange(m): for j inrange(n): if board[i][j] == "O": board[i][j] = "X" if board[i][j] == "A": board[i][j] = "O"
defsolve(self, board: List[List[str]]) -> None: """ Do not return anything, modify board in-place instead. """
# 边缘的O都变成A,将其余的O变成X,再将所有的A变成O defbfs(board, x, y): queue = deque([(x, y)]) board[x][y] = "A" while queue: x, y = queue.popleft() for dx, dy in self.dir: nextx = x + dx nexty = y + dy if ( nextx < 0 or nextx >= len(board) or nexty < 0 or nexty >= len(board[0]) ): continue if board[nextx][nexty] == "O": board[nextx][nexty] = "A" queue.append((nextx, nexty))
m, n = len(board), len(board[0])
for i inrange(m): for j inrange(n): if ( i == 0or i == len(board) - 1or j == 0or j == len(board[0]) - 1 ) and board[i][j] == "O": bfs(board, i, j) # print(board) for i inrange(m): for j inrange(n): if board[i][j] == "O": board[i][j] = "X" if board[i][j] == "A": board[i][j] = "O"
defpacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]: m, n = len(heights), len(heights[0]) res = [] visited = [ [[False] * 2for _ inrange(n)] for _ inrange(m) ] # 用来标记当前位置是否能从太平洋或者大西洋到达 0:太平洋 1:大西洋
for i inrange(m): for j inrange(n): if i == 0or j == 0: visited[i][j][0] = True self.dfs(heights, visited, i, j, 0) if i == m - 1or j == n - 1: visited[i][j][1] = True self.dfs(heights, visited, i, j, 1) for i inrange(m): for j inrange(n): if visited[i][j][0] and visited[i][j][1]: res.append([i, j]) return res
defdfs(self, heights, visited, x, y, flag): for dx, dy in self.direction: nextx = x + dx nexty = y + dy # 如果当前位置的高度高于x,y的高度,需要跳过 if ( nextx < 0 or nextx >= len(heights) or nexty < 0 or nexty >= len(heights[0]) or heights[nextx][nexty] < heights[x][y] or visited[nextx][nexty][flag] ): continue # if visited[nextx][nexty][flag] == False: visited[nextx][nexty][flag] = True self.dfs(heights, visited, nextx, nexty, flag)
defpacificAtlantic(self, heights): m, n = len(heights), len(heights[0]) res = [] visited = [[[False] * 2for _ inrange(n)] for _ inrange(m)] # 用来标记当前位置是否能从太平洋或者大西洋到达 0:太平洋 1:大西洋
for i inrange(m): for j inrange(n): if i == 0or j == 0: self.bfs(heights, visited, i, j, 0) if i == m - 1or j == n - 1: self.bfs(heights, visited, i, j, 1) for i inrange(m): for j inrange(n): if visited[i][j][0] and visited[i][j][1]: res.append([i, j]) return res
defbfs(self, heights, visited, x, y, flag): queue = deque([(x, y)]) visited[x][y][flag] = True while queue: x, y = queue.popleft() for dx, dy in self.direction: nextx = x + dx nexty = y + dy if nextx < 0or nextx >= len(heights) or nexty < 0or nexty >= len(heights[0]) or heights[nextx][ nexty] < heights[x][y] or visited[nextx][nexty][flag]: continue visited[nextx][nexty][flag] = True queue.append((nextx, nexty))
if __name__ == '__main__': s = Solution() # heights = [[1, 2, 2, 3, 5], [3, 2, 3, 4, 4], [2, 4, 5, 3, 1], [6, 7, 1, 4, 5], [5, 1, 1, 2, 4]] # heights = [[2, 1], [1, 2]] heights = [[1, 2, 2, 3, 5], [3, 2, 3, 4, 4], [2, 4, 5, 3, 1], [6, 7, 1, 4, 5], [5, 1, 1, 2, 4]] res = s.pacificAtlantic(heights) print(res) # visited = [[[False] * 2 for _ in range(3)] for _ in range(5)] # for i in range(len(visited)): # for j in range(len(visited[0])): # print(visited[i][j][0])
defbfs(self, grid, visited): res = 0 m, n = len(grid), len(grid[0]) queue = deque() for i inrange(m): for j inrange(n): if grid[i][j] == 2: queue.append((i, j, 0)) while queue: x, y, num = queue.popleft() res = max(res, num) # 更新最新的分钟数 visited[x][y] = True for dx, dy in self.directions: nextx = x + dx nexty = y + dy if nextx < 0or nextx >= m or nexty < 0or nexty >= n: continue if grid[nextx][nexty] == 1andnot visited[nextx][nexty]: queue.append((nextx, nexty, num + 1)) visited[nextx][nexty] = True grid[nextx][nexty] = 2 return res
deforangesRotting(self, grid: List[List[int]]) -> int: m, n = len(grid), len(grid[0]) visited = [[False] * n for _ inrange(m)] res = self.bfs(grid, visited) for i inrange(m): for j inrange(n): if grid[i][j] == 1: return -1 return res
deforangesRotting(self, grid: List[List[int]]) -> int: m, n = len(grid), len(grid[0]) queue = deque() fresh = 0 res = 0 for i inrange(m): for j inrange(n): if grid[i][j] == 2: queue.append((i, j)) elif grid[i][j] == 1: fresh += 1 while queue and fresh: for _ inrange(len(queue)): x, y = queue.popleft() for dx, dy in self.direction: nextx, nexty = x + dx, y + dy if nextx < 0or nextx >= m or nexty < 0or nexty >= n: continue if grid[nextx][nexty] == 1: grid[nextx][nexty] = 2 queue.append((nextx, nexty)) fresh -= 1 res += 1 return res if fresh == 0else -1
deflargestIsland(self, grid) -> int: m, n = len(grid), len(grid[0]) visited = [[False] * n for _ inrange(m)] tag = 2 for i inrange(m): for j inrange(n): if grid[i][j] == 1andnot visited[i][j]: tmp = self.bfs(grid, visited, i, j, tag) self.area[tag].append(tmp) self.area[tag].append(False) tag += 1 print(self.area) # {2: 3, 3: 3} singleMaxArea = max(self.area[i][0] for i in self.area) if self.area else0 for g in grid: print(g) maxArea = 0 for i inrange(m): for j inrange(n): if grid[i][j] == 0: for v in self.area.values(): v[1] = False tmpArea = 1 for dx, dy in self.direction: if i + dx < 0or i + dx >= len(grid) or j + dy < 0or j + dy >= len(grid[0]): continue if grid[i + dx][j + dy] in self.area andnot self.area[grid[i + dx][j + dy]][1]: tmpArea += self.area[grid[i + dx][j + dy]][0] self.area[grid[i + dx][j + dy]][1] = True # print(tmpArea) maxArea = max(maxArea, tmpArea) return maxArea if maxArea != 0else singleMaxArea
defbfs(self, grid, visited, x, y, tag): tmp = 1 queue = deque([(x, y)]) visited[x][y] = True grid[x][y] = tag while queue: x, y = queue.popleft() for dx, dy in self.direction: nextx = x + dx nexty = y + dy if nextx < 0or nextx >= len(grid) or nexty < 0or nexty >= len(grid[0]): continue if grid[nextx][nexty] == 1andnot visited[nextx][nexty]: tmp += 1 visited[nextx][nexty] = True grid[nextx][nexty] = tag queue.append((nextx, nexty)) return tmp
deflargestIsland(self, grid) -> int: m, n = len(grid), len(grid[0]) visited = [[False] * n for _ inrange(m)] tag = 2 # 遍历矩阵,统计其中的岛屿面积 for i inrange(m): for j inrange(n): if grid[i][j] == 1andnot visited[i][j]: tmp = self.bfs(grid, visited, i, j, tag) self.area[tag] = tmp tag += 1 # print(self.area) # {2: [3,False], 3: [3,False]} # 同来解决全部是0的情况 singleMaxArea = max(self.area[i] for i in self.area.keys()) if self.area else0 # for g in grid: # print(g) maxArea = 0 for i inrange(m): for j inrange(n): if grid[i][j] == 0: # 每轮进行初始化 mset = set() tmpArea = 1 for dx, dy in self.direction: nextx = i + dx nexty = j + dy if nextx < 0or nextx >= len(grid) or nexty < 0or nexty >= len(grid[0]): continue mset.add(grid[nextx][nexty]) for m in mset: tmpArea += self.area.get(m, 0) maxArea = max(maxArea, tmpArea)
# print(tmpArea) return maxArea if maxArea != 0else singleMaxArea
defbfs(self, grid, visited, x, y, tag): tmp = 1 queue = deque([(x, y)]) visited[x][y] = True grid[x][y] = tag while queue: x, y = queue.popleft() for dx, dy in self.direction: nextx = x + dx nexty = y + dy if nextx < 0or nextx >= len(grid) or nexty < 0or nexty >= len(grid[0]): continue if grid[nextx][nexty] == 1andnot visited[nextx][nexty]: tmp += 1 visited[nextx][nexty] = True grid[nextx][nexty] = tag queue.append((nextx, nexty)) return tmp
defislandPerimeter(self, grid) -> int: m, n = len(grid), len(grid[0]) res = 0 for i inrange(m): for j inrange(n): if grid[i][j] == 1: # 岛屿 # 遍历四周是海洋还是岛屿 for dx, dy in self.direction: nextx = i + dx nexty = j + dy if ( nextx < 0 or nextx >= m or nexty < 0 or nexty >= n or grid[nextx][nexty] == 0 ): res += 1 return res
defislandPerimeter(self, grid) -> int: m, n = len(grid), len(grid[0]) res = 0# 记录岛屿的数量 adj = 0 for i inrange(m): for j inrange(n): if grid[i][j] == 1: res += 1 for dx, dy in self.direction: nextx = i + dx nexty = j + dy if nextx < 0or nextx >= m or nexty < 0or nexty >= n: continue if grid[nextx][nexty] == 1: adj += 1 print(res, adj) return res * 4 - adj
defisTreeAfterRemoveEdge(self, edges, index): for i inrange(len(edges)): if i == index: continue if self.isSame(edges[i][0], edges[i][1]): returnFalse self.join(edges[i][0], edges[i][1]) returnTrue
defgetRemovedEdge(self, edges): for i inrange(len(edges)): if self.isSame(edges[i][0], edges[i][1]): return edges[i] self.join(edges[i][0], edges[i][1]) return []
# 判断删除指定边之后是否仍然构成树结构 defisTreeAfterRemoveEdge(self, edges, index): for i inrange(len(edges)): if i == index: continue if self.isSame(edges[i][0], edges[i][1]): returnFalse self.join(edges[i][0], edges[i][1]) returnTrue
defgetRemovedEdge(self, edges): for i inrange(len(edges)): if self.isSame(edges[i][0], edges[i][1]): return edges[i] self.join(edges[i][0], edges[i][1]) return []
deffindCircleNum(self, isConnected) -> int: n = len(isConnected) visited = [False] * n res = 0 queue = deque() for i inrange(n): # 用来防止出现单独的节点 ifnot visited[i]: self.bfs(i, isConnected, n, queue, visited) res += 1 return res
defbfs(self, i, isConnected, n, queue, visited): queue.append(i) while queue: cur = queue.popleft() for j inrange(n): if isConnected[cur][j] == 1andnot visited[j]: queue.append(j) visited[j] = True
DFS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
classSolution: defdfs(self, i, visited, isConnected): for j inrange(len(isConnected)): if isConnected[i][j] == 1andnot visited[j]: visited[i] = True self.dfs(j, visited, isConnected)
deffindCircleNum(self, isConnected) -> int: n = len(isConnected) visited = [False] * n res = 0 for i inrange(n): ifnot visited[i]: res += 1 self.dfs(i, visited, isConnected) return res
课程表
本题是一个经典的拓扑排序问题,其中解决方法如下:
如果满足拓扑排序,那么其经过的次数最终应该就是拓扑排序的次数【BFS】
通过dfs判断有向图中是否存在环路【DFS】
方法一:
首先生成一个入度表indegrees
使用一个队列queue,将所有入度为0的节点入队
当queue不为空时,依次将堆首节点出队,在课程安排图中删除此节点pre
并不是真正从邻接表中删除此节点,而是将此节点对应的入度-1。
在每次pre出队时,执行numCourses--
拓扑排序的次数等于课程个数,最后只需要判断numCourses==0即可判断是否成功安排课程表。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution: defcanFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool: indegrees = [0for _ inrange(numCourses)] adjacency = [[] for _ inrange(numCourses)] queue = deque() for cur, pre in prerequisites: indegrees[cur] += 1 adjacency[pre].append(cur) for i inrange(len(indegrees)): ifnot indegrees[i]: queue.append(i) while queue: pre = queue.popleft() numCourses -= 1 for cur in adjacency[pre]: indegrees[cur] -= 1 ifnot indegrees[cur]: # 入度也为0的 加入 queue.append(cur) return numCourses == 0