Day9,Hot100(图论)

打印 上一主题 下一主题

主题 843|帖子 843|积分 2531

图论

图论部分保举 acm 模式,由于图的输入处置惩罚不一样
DFS,雷同二叉树的递归遍历
BFS,雷同二叉树的层次遍历
208. 实现 Trie (前缀树)

数据结构大概如下:


  • 可以当作是 二十六叉树 (由于26个小写字母)

  1. class Node:
  2.     def __init__(self):
  3.         self.son = {}
  4.         self.end = False  # end=True, 表示当前结点已经构成一个单词
  5. class Trie:
  6.     def __init__(self):
  7.         self.root = Node()
  8.     def insert(self, word: str) -> None:
  9.         cur = self.root
  10.         for c in word:
  11.             if c not in cur.son:
  12.                 cur.son[c] = Node()
  13.             cur = cur.son[c]
  14.         cur.end = True
  15.     def find(self, word: str) -> int:
  16.         cur = self.root
  17.         for c in word:
  18.             if c not in cur.son:
  19.                 return 0
  20.             cur = cur.son[c]
  21.         return 2 if cur.end else 1
  22.     def search(self, word: str) -> bool:
  23.         return self.find(word) == 2
  24.     def startsWith(self, prefix: str) -> bool:
  25.         return self.find(prefix) != 0
复制代码

DFS

(1)200. 岛屿数量

方法一:DFS
  1. class Solution:
  2.     def numIslands(self, grid: List[List[str]]) -> int:
  3.         dx = [0,-1,0,1]
  4.         dy = [-1,0,1,0]
  5.         def dfs(i, j):
  6.             if (not 0 <= i < m) or (not 0 <= j < n) or grid[i][j] == '0':
  7.                 return
  8.             grid[i][j] = '0'
  9.             for idx in range(4):
  10.                 x = i + dx[idx]
  11.                 y = j + dy[idx]
  12.                 dfs(x,y)
  13.         m = len(grid)
  14.         n = len(grid[0])
  15.         ans = 0
  16.         for i in range(m):
  17.             for j in range(n):
  18.                 if grid[i][j] == "1":
  19.                     dfs(i,j)  # 把整个岛都标记
  20.                     ans += 1
  21.         return ans
复制代码
ACM 代码模式:99. 岛屿数量

读取每一行输入map(int, input().split())


  • input().split(),将输入的行,按照空格切分每个元素,返回一个list
  • map(int, input().split()),将 list 中每个元素转化为指定的 int范例,返回一个可迭代的对象
比方输入1 2 3 4


  • input().split(),得到[‘1’, ‘2’, ‘3’, ‘4’]
  • list(map(int, input().split())),[1, 2, 3, 4]
  1. dx = [-1,0,1,0]
  2. dy = [0,-1,0,1]
  3. def dfs(i, j):
  4.     if not (0<=i<n) or not (0<=j<m) or grid[i][j]==0:
  5.         return
  6.    
  7.     grid[i][j] = 0
  8.    
  9.     for idx in range(4):
  10.         x = dx[idx] + i
  11.         y = dy[idx] + j
  12.         dfs(x, y)
  13. if __name__ == '__main__':
  14.     n,m = map(int, input().split())
  15.     grid = []
  16.     for i in range(n):
  17.         grid.append(list(map(int, input().split())))
  18.    
  19.     # visited = [ [False] * m for _ in range(n) ]
  20.    
  21.     ans = 0
  22.    
  23.     for i in range(n):
  24.         for j in range(m):
  25.             if grid[i][j] == 1:
  26.                 dfs(i, j)
  27.                 ans += 1
  28.    
  29.     print(ans)
复制代码

(2)100. 岛屿的最大面积


  1. dx = [-1, 0, 1, 0]
  2. dy = [0, -1, 0, 1]
  3. s = 0
  4. def dfs(i, j):
  5.     if not (0 <= i < n) or not (0 <= j < m) or grid[i][j] == 0:
  6.         return
  7.     global s
  8.     s += 1
  9.     grid[i][j] = 0
  10.     for idx in range(4):
  11.         x = dx[idx] + i
  12.         y = dy[idx] + j
  13.         dfs(x, y)
  14. if __name__ == '__main__':
  15.     n, m = map(int, input().split())
  16.     grid = []
  17.     for i in range(n):
  18.         grid.append(list(map(int, input().split())))
  19.     ans = 0
  20.     for i in range(n):
  21.         for j in range(m):
  22.             if grid[i][j] == 1:
  23.                 s = 0
  24.                 dfs(i, j)
  25.                 ans = max(ans, s)
  26.     print(ans)
复制代码

(3)101. 孤岛的总面积



步骤


  • 首先把四周靠边界的岛屿都设为 0
  • 然后遍历剩余的孤岛面积
  1. dx = [-1,0,1,0]
  2. dy = [0,-1,0,1]
  3. s = 0
  4. def dfs(i,j):
  5.     if not (0<=i<n) or not (0<=j<m) or grid[i][j] == 0:
  6.         return
  7.     global s
  8.     s += 1
  9.     grid[i][j] = 0
  10.     for idx in range(4):
  11.         x = dx[idx] + i
  12.         y = dy[idx] + j
  13.         dfs(x,y)
  14. if __name__ == '__main__':
  15.     n, m = map(int, input().split())
  16.     grid = []
  17.     for i in range(n):
  18.         grid.append(list(map(int, input().split())))
  19.     # 将四周贴边的非孤岛区域转为水
  20.     # 遍历第一列和最后一列
  21.     for i in range(n):
  22.         if grid[i][0] == 1:
  23.             dfs(i,0)
  24.         elif grid[i][m-1] == 1:
  25.             dfs(i,m-1)
  26.     # 遍历第一行和最后一行
  27.     for j in range(m):
  28.         if grid[0][j] == 1:
  29.             dfs(0,j)
  30.         elif grid[n-1][j] == 1:
  31.             dfs(n-1,j)
  32.     # 计算孤岛面积
  33.     s = 0
  34.     for i in range(n):
  35.         for j in range(m):
  36.             if grid[i][j] == 1:
  37.                 dfs(i,j)
  38.     print(s)
复制代码

(4)102. 沉没孤岛



  • 把靠四周的非孤岛标记为2
  • 接着把剩余的1(孤岛),标记为0
  • 末了把2修改回1
  1. dx = [-1,0,1,0]
  2. dy = [0,-1,0,1]
  3. def dfs(i,j):
  4.     if not (0 <= i < n) or not(0 <= j < m) or grid[i][j] != 1:
  5.         return
  6.    
  7.     grid[i][j] = 2
  8.    
  9.     for k in range(4):
  10.         x = dx[k] + i
  11.         y = dy[k] + j
  12.         dfs(x,y)
  13. if __name__ == '__main__':
  14.     n,m = map(int, input().split())
  15.     grid = []
  16.    
  17.     for _ in range(n):
  18.         grid.append(list(map(int, input().split())))
  19.    
  20.     for i in range(n):
  21.         if grid[i][0] == 1:
  22.             dfs(i, 0)
  23.         if grid[i][m-1] == 1:
  24.             dfs(i, m-1)
  25.    
  26.     for j in range(m):
  27.         if grid[0][j] == 1:
  28.             dfs(0,j)
  29.         if grid[n-1][j] == 1:
  30.             dfs(n-1, j)
  31.             
  32.     for i in range(n):
  33.         for j in range(m):
  34.             if grid[i][j] == 1:
  35.                 grid[i][j] = 0
  36.             elif grid[i][j] == 2:
  37.                 grid[i][j] = 1
  38.         print(' '.join(map(str, grid[i])))
复制代码

BFS

(1)994. 腐烂的橘子

使用 BFS 是为了实现,同一个时间,当前所有腐烂的橘子同时腐烂周围
  1. from collections import deque
  2. class Solution:
  3.     def orangesRotting(self, grid: List[List[int]]) -> int:
  4.         n, m = len(grid), len(grid[0])
  5.         q = deque()
  6.         
  7.         count = 0  # 新鲜橘子数
  8.         for i in range(n):
  9.             for j in range(m):
  10.                 if grid[i][j] == 1:
  11.                     count += 1
  12.                 elif grid[i][j] == 2:
  13.                     q.append((i,j))
  14.         dx = [-1,0,1,0]
  15.         dy = [0,-1,0,1]
  16.         round = 0  # 分钟数
  17.         while count > 0 and len(q) > 0:
  18.             round += 1
  19.             cur = len(q)  # 这一轮有多少个腐烂的橘子一起腐烂周围
  20.             for _ in range(cur):
  21.                 i,j = q.popleft()
  22.                 for idx in range(4):
  23.                     x = dx[idx] + i
  24.                     y = dy[idx] + j
  25.                     if (0<=x<n) and (0<=y<m) and grid[x][y] == 1:
  26.                         grid[x][y] = 2
  27.                         count -= 1
  28.                         q.append((x,y))
  29.         if count > 0:
  30.             return -1
  31.         else:
  32.             return round
复制代码

(2)207. 课程表



  • 每次只能修当前可以修的课程——入度为0的课程
  • 修完一轮后,再修可以休的课程——入度变为0的课程
  • 以是我们必要记录每个课程的入度,
  • 然后必要毗邻矩阵来关联课程之间的关系,从而更新入度

  1. from collections import deque
  2. class Solution:
  3.     def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
  4.         indegree = [0] * numCourses  # 每个课程的入度(即先修课程有几门)
  5.         adj = defaultdict(list) # key为当前课,value为它的后续课程,用列表存
  6.         # 初始化入度和邻接表
  7.         for cur,pre in prerequisites:
  8.             indegree[cur] += 1
  9.             adj[pre].append(cur)
  10.         # 把入度为0的入队列
  11.         q = deque()
  12.         for i in range(numCourses):
  13.             if indegree[i] == 0:
  14.                 q.append(i)
  15.         
  16.         while q:
  17.             n = len(q)
  18.             for i in range(n):
  19.                 pre = q.popleft()
  20.                 numCourses -= 1
  21.                 # 遍历课程pre的邻接表:它的后续课程
  22.                 for cur in adj[pre]:
  23.                     # 将后续课程的入度 -1
  24.                     indegree[cur] -= 1
  25.                     if indegree[cur] == 0:
  26.                         q.append(cur)
  27.    
  28.         return numCourses == 0
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

拉不拉稀肚拉稀

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表