0
点赞
收藏
分享

微信扫一扫

Vuepress的使用

前言

  • 干活炼丹闲暇之余来刷刷题!NoNo应该说刷题闲暇才炼丹

994. 腐烂的橘子 - 力扣(LeetCode)

  • BFS队列

    • 参考橘子哥的题解
    • class Solution:
          def orangesRotting(self, grid: List[List[int]]) -> int:
              row, col, time = len(grid), len(grid[0]), 0
              q = deque()  # 把所有腐烂橘子存入队列,多点开花
              for i in range(row):
                  for j in range(col):
                      if grid[i][j] == 2:
                          q.append((i, j, 0))  # 0标记当前时间/深度
              # 多源BFS过程
              while q:
                  i, j, time = q.popleft()
                  for i0, j0 in ((i-1,j), (i, j-1), (i+1, j), (i, j+1)):
                      if 0 <= i0 < row and 0 <= j0 < col and grid[i0][j0] == 1:
                          grid[i0][j0] = 2
                          q.append((i0, j0, time+1))
              if any(1 in row for row in grid):
                  return -1  #  如果最后还有新鲜橘子就返回-1
              return time
  • BFS双集合

    • class Solution:
          def orangesRotting(self, grid: List[List[int]]) -> int:
              row = len(grid)
              col = len(grid[0])
              rotten = {(i, j) for i in range(row) for j in range(col) if grid[i][j] == 2} # 腐烂集合
              fresh = {(i, j) for i in range(row) for j in range(col) if grid[i][j] == 1}  # 新鲜集合
              time = 0
              while fresh:
                  if not rotten: return -1  # 没有腐烂有新鲜
                  # 遍历腐烂的,感染周围新鲜一波,原来腐烂的从集合中删除,新腐烂加进集合
                  rotten = {(i + di, j + dj) for i, j in rotten for di, dj in [(0, 1), (0, -1), (1, 0), (-1, 0)] if (i + di, j + dj) in fresh}
                  fresh -= rotten # 剔除腐烂的
                  time += 1
              return time
      

207. 课程表 - 力扣(LeetCode)

  • BFS拓扑排序

    • 判断是否是有向无环图(DAG)用到拓扑排序,学习一下B站视频题解

    • class Solution:
          def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
              indegrees = [0] * numCourses  # 入度数组(列表,保存所有课程的依赖课程总数)
              relations_list = collections.defaultdict(list)  # 邻接表(字典,保存所有课程与依赖课程的关系,int:list)
              # relations_list = [[] for _ in range(numCourses)]  # 也可以用二维数组
              for cur, pre in prerequisites:
                  indegrees[cur] += 1  # 保存课程初始入度值
                  relations_list[pre].append(cur)  # 添加依赖它的后续课程
              q = deque()
              for i in range(len(indegrees)):
                  if indegrees[i] == 0:
                      q.append(i)  # 将入度为0的课程入列
              # dfs
              while q:
                  cur = q.popleft()
                  numCourses -= 1  # 选掉一门课
                  relations = relations_list[cur]
                  for i in relations: 
                      indegrees[i] -= 1  # 如果存在后续课程则后续课程入度-1
                      if indegrees[i] == 0:
                          q.append(i)  # 将入度为0的课程入列
              # 如果上完了说明没有环
              return numCourses == 0
  • DFS判断环

    • 参考K神题解
    • class Solution:
          def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
              def dfs(i, adjacency, flags):
                  if flags[i] == -1: return True  # 别人走过的,没问题
                  if flags[i] == 1: return False  # 走过走过的,坏了,告诉上一层
                  flags[i] = 1  # 1表示我自己走的
                  for j in adjacency[i]:
                      if not dfs(j, adjacency, flags): return False  # 接收下层的信号,此路有环!
                  flags[i] = -1  # -1表示别人走的
                  return True
              adjacency = [[] for _ in range(numCourses)]
              flags = [0 for _ in range(numCourses)]  # 0表示没走过
              for cur, pre in prerequisites:
                  adjacency[pre].append(cur)
              for i in range(numCourses):
                  if not dfs(i, adjacency, flags): 
                      return False  # 如果有路坏的就有环
              return True

208. 实现 Trie (前缀树) - 力扣(LeetCode) 

  • 前缀树

    • 这也是图?没都没听过,学习一下小白题解
    • # 节点类
      class Node:
          def __init__(self):
              self.is_end = False     # 标记是否到达单词结尾
              self.next = [None]*26   # 每个位置对应一个字母,连下一个节点
      # 前缀树类
      class Trie:
          # 初始化根节点
          def __init__(self):
              self.root = Node()
          # 插入单词:匹配前缀 + 补充剩余
          def insert(self, word: str) -> None:
              cur = self.root
              for c in word:
                  c_index = ord(c) - ord('a')
                  if not cur.next[c_index]:
                      cur.next[c_index] = Node()  # 前缀匹配到存在该字母
                  cur = cur.next[c_index]
              cur.is_end = True
          # 搜索单词:匹配前缀,检查是否为结尾
          def search(self, word: str) -> bool:
              cur = self.root
              for c in word:
                  c_index = ord(c) - ord('a')
                  if cur.next[c_index]:
                      cur = cur.next[c_index]
                  else:
                      return False
              return cur.is_end
          # 匹配前缀
          def startsWith(self, prefix: str) -> bool:
              cur = self.root
              for c in prefix:
                  c_index = ord(c) - ord('a')
                  if cur.next[c_index]:
                      cur = cur.next[c_index]
                  else:
                      return False
              return True
      
      # Your Trie object will be instantiated and called as such:
      # obj = Trie()
      # obj.insert(word)
      # param_2 = obj.search(word)
      # param_3 = obj.startsWith(prefix)

后言

  •  这几个今天都没怎么接触,学完感觉头好痒,啊啊啊要长脑子了
举报

相关推荐

0 条评论