class Solution:
def dfs(self, grid: List[List[str]], r: int, c: int) -> None:
"""
深度优先搜索函数,用于遍历并标记与当前位置(r, c)相连的所有陆地
(即值为"1"的格子)为已访问(即标记为0)。
:param grid: 二维网格,其中的每个元素都是'0'或'1'。
:param r: 当前遍历到的行索引。
:param c: 当前遍历到的列索引。
"""
grid[r][c] = '0' # 将当前位置标记为已访问(即陆地变为水)
nr, nc = len(grid), len(grid[0]) # 获取网格的行数和列数
# 遍历当前位置的上下左右四个相邻位置
for x, y in [(r - 1, c), (r + 1, c), (r, c - 1), (r, c + 1)]:
# 检查相邻位置是否在网格范围内且为陆地(即值为'1')
if 0 <= x < nr and 0 <= y < nc and grid[x][y] == "1":
self.dfs(grid, x, y) # 递归地遍历相邻的陆地
def numIslands(self, grid: List[List[str]]) -> int:
"""
计算给定网格中的岛屿数量。
:param grid: 二维网格,其中的每个元素都是'0'或'1'。
:return: 网格中的岛屿数量。
"""
nr = len(grid)
if nr == 0: # 如果网格为空,则岛屿数量为0
return 0
nc = len(grid[0]) # 获取网格的列数
num_islands = 0 # 初始化岛屿数量为0
for r in range(nr): # 遍历网格的每一行
for c in range(nc): # 遍历网格的每一列
if grid[r][c] == "1": # 如果当前位置是陆地
num_islands += 1 # 岛屿数量加1
self.dfs(grid, r, c) # 调用dfs函数遍历并标记与当前陆地相连的所有陆地
return num_islands # 返回岛屿数量
python复制代码
class Solution:
def orangesRotting(self, grid: List[List[int]]) -> int:
R, C = len(grid), len(grid[0]) # 获取网格的行数和列数
# 初始化一个队列,用于存放腐烂橙子(值为2)的位置及其腐烂时间(初始为0)
queue = deque()
for r, row in enumerate(grid):
for c, val in enumerate(row):
if val == 2:
queue.append((r, c, 0))
# 定义一个辅助函数,用于生成当前橙子位置(r, c)的上下左右四个相邻位置
def neighbors(r, c):
for nr, nc in ((r - 1, c), (r, c - 1), (r + 1, c), (r, c + 1)):
if 0 <= nr < R and 0 <= nc < C: # 确保相邻位置在网格范围内
yield nr, nc
d = 0 # 初始化腐烂时间计数器
while queue: # 当队列不为空时,继续执行
r, c, d = queue.popleft() # 从队列中取出腐烂橙子的位置及其腐烂时间
for nr, nc in neighbors(r, c): # 遍历当前腐烂橙子的四个相邻位置
if grid[nr][nc] == 1: # 如果相邻位置是新鲜的橙子
grid[nr][nc] = 2 # 将其标记为腐烂的橙子
queue.append((nr, nc, d + 1)) # 将其加入队列,并更新腐烂时间为当前时间+1
# 检查网格中是否还有新鲜的橙子(值为1)
if any(1 in row for row in grid):
return -1 # 如果有,说明无法让所有橙子都腐烂,返回-1
return d # 否则,返回最后的腐烂时间
python复制代码
class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
# 创建一个defaultdict来存储课程的邻接表,即每个课程的后继课程列表
edges = collections.defaultdict(list)
# 创建一个列表来存储每个课程的入度(即有多少课程是该课程的前置课程)
indeg = [0] * numCourses
# 遍历先决条件列表,构建邻接表和入度列表
for info in prerequisites:
# info[1] 是当前课程,info[0] 是其前置课程
# 将当前课程(info[1])的后继课程(info[0])添加到邻接表中
edges[info[1]].append(info[0])
# 将前置课程(info[0])的入度加1
indeg[info[0]] += 1
# 创建一个双端队列,用于存储入度为0的课程(即没有前置课程的课程)
q = collections.deque([u for u in range(numCourses) if indeg[u] == 0])
# 初始化已访问(或已完成)的课程数
visited = 0
# 使用广度优先搜索(BFS)遍历课程
while q:
# 每从队列中取出一个课程,表示该课程可以完成
visited += 1
u = q.popleft()
# 遍历当前课程的所有后继课程
for v in edges[u]:
# 将后继课程的入度减1,表示完成了一个前置课程
indeg[v] -= 1
# 如果后继课程的入度变为0,说明其所有前置课程都已完成,可以加入队列继续搜索
if indeg[v] == 0:
q.append(v)
# 如果已访问的课程数等于总课程数,说明所有课程都可以完成
# 否则,存在环,无法完成所有课程
return visited == numCourses
python复制代码
class Trie:
def __init__(self):
# 初始化Trie节点,children是一个长度为26的列表,
# 用于存储指向子节点的引用(假设只处理小写字母a-z)
# 每个位置对应一个字母(例如,0对应'a',1对应'b',...,25对应'z')
# isEnd用于标记该节点是否是某个单词的结尾
self.children = [None] * 26
self.isEnd = False
def searchPrefix(self, prefix: str) -> "Trie":
# 搜索并返回给定前缀对应的最后一个Trie节点
# 如果前缀不存在于Trie中,则返回None
node = self # 从根节点开始搜索
for ch in prefix:
# 将字符转换为对应的索引('a'->0, 'b'->1, ..., 'z'->25)
ch = ord(ch) - ord("a")
# 如果当前节点的children中对应字符的节点不存在,说明前缀不存在,返回None
if not node.children[ch]:
return None
# 否则,移动到子节点继续搜索
node = node.children[ch]
# 如果所有字符都成功匹配,返回最后一个节点
return node
def insert(self, word: str) -> None:
# 将一个单词插入到Trie中
node = self # 从根节点开始插入
for ch in word:
# 将字符转换为对应的索引
ch = ord(ch) - ord("a")
# 如果当前节点的children中对应字符的节点不存在,则创建一个新的Trie节点
if not node.children[ch]:
node.children[ch] = Trie()
# 移动到子节点继续插入
node = node.children[ch]
# 标记最后一个节点为单词的结尾
node.isEnd = True
def search(self, word: str) -> bool:
# 搜索Trie中是否存在一个完整的单词
# 使用searchPrefix找到最后一个节点,然后检查该节点是否是某个单词的结尾
node = self.searchPrefix(word)
return node is not None and node.isEnd
def startsWith(self, prefix: str) -> bool:
# 检查Trie中是否存在以给定前缀开头的单词
# 使用searchPrefix找到最后一个节点,如果找到,则说明存在以该前缀开头的单词
return self.searchPrefix(prefix) is not None
# 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)