leetcode 399 除法求值
给你一个变量对数组 equations
和一个实数值数组 values
作为已知条件,其中 equations[i] = [Ai, Bi]
和 values[i]
共同表示等式 Ai / Bi = values[i]
。每个 Ai
或 Bi
是一个表示单个变量的字符串。
另有一些以数组 queries
表示的问题,其中 queries[j] = [Cj, Dj]
表示第 j
个问题,请你根据已知条件找出 Cj / Dj = ?
的结果作为答案。
返回 所有问题的答案 。如果存在某个无法确定的答案,则用 -1.0
替代这个答案。如果问题中出现了给定的已知条件中没有出现的字符串,也需要用 -1.0
替代这个答案。
注意:输入总是有效的。你可以假设除法运算中不会出现除数为 0 的情况,且不存在任何矛盾的结果。
注意:未在等式列表中出现的变量是未定义的,因此无法确定它们的答案。
示例 1:
输入:equations = [["a","b"],["b","c"]], values = [2.0,3.0], queries = [["a","c"],["b","a"],["a","e"],["a","a"],["x","x"]] 输出:[6.00000,0.50000,-1.00000,1.00000,-1.00000] 解释: 条件:a / b = 2.0, b / c = 3.0 问题:a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? 结果:[6.0, 0.5, -1.0, 1.0, -1.0 ] 注意:x 是未定义的 => -1.0示例 2:
输入:equations = [["a","b"],["b","c"],["bc","cd"]], values = [1.5,2.5,5.0], queries = [["a","c"],["c","b"],["bc","cd"],["cd","bc"]] 输出:[3.75000,0.40000,5.00000,0.20000]示例 3:
输入:equations = [["a","b"]], values = [0.5], queries = [["a","b"],["b","a"],["a","c"],["x","y"]] 输出:[0.50000,2.00000,-1.00000,-1.00000]
有点难,看题解理一下思路
首先初始化一下,equations和values可以看作一个带权的有向图,比如["a","b"]=2,a->b的边权值是2.0,b->a的边权值是0.5
然后对于queries的每一个元素,queries[i][0]作为起点,queries[i][1]作为终点,BFS搜索即可
class Solution(object):
def calcEquation(self, equations, values, queries):
"""
:type equations: List[List[str]]
:type values: List[float]
:type queries: List[List[str]]
:rtype: List[float]
"""
def bfs(start, end):
if start not in neighbours:
return -1.0
queue = deque([(start, 1.0)])
visited = set()
while queue:
node, val = queue.popleft()
if node == end:
return val
for i in neighbours[node]:
if i not in visited:
visited.add(i)
queue.append((i, val*results[node][i]))
return -1.0
neighbours = defaultdict(set)
results = defaultdict(dict)
for i in range(len(equations)):
node1, node2 = equations[i]
neighbours[node1].add(node2)
neighbours[node2].add(node1)
results[node1][node2] = values[i]
results[node2][node1] = 1.0 / values[i]
ans_arr = []
for j in range(len(queries)):
start, end = queries[j]
ans = bfs(start, end)
ans_arr.append(ans)
return ans_arr
leetcode 1926 迷宫中离入口最近的出口
给你一个 m x n
的迷宫矩阵 maze
(下标从 0 开始),矩阵中有空格子(用 '.'
表示)和墙(用 '+'
表示)。同时给你迷宫的入口 entrance
,用 entrance = [entrancerow, entrancecol]
表示你一开始所在格子的行和列。
每一步操作,你可以往 上,下,左 或者 右 移动一个格子。你不能进入墙所在的格子,你也不能离开迷宫。你的目标是找到离 entrance
最近 的出口。出口 的含义是 maze
边界 上的 空格子。entrance
格子 不算 出口。
请你返回从 entrance
到最近出口的最短路径的 步数 ,如果不存在这样的路径,请你返回 -1
。
示例 1:
输入:maze = [["+","+",".","+"],[".",".",".","+"],["+","+","+","."]], entrance = [1,2] 输出:1 解释:总共有 3 个出口,分别位于 (1,0),(0,2) 和 (2,3) 。 一开始,你在入口格子 (1,2) 处。 - 你可以往左移动 2 步到达 (1,0) 。 - 你可以往上移动 1 步到达 (0,2) 。 从入口处没法到达 (2,3) 。 所以,最近的出口是 (0,2) ,距离为 1 步。示例 2:
输入:maze = [["+","+","+"],[".",".","."],["+","+","+"]], entrance = [1,0] 输出:2 解释:迷宫中只有 1 个出口,在 (1,2) 处。 (1,0) 不算出口,因为它是入口格子。 初始时,你在入口与格子 (1,0) 处。 - 你可以往右移动 2 步到达 (1,2) 处。 所以,最近的出口为 (1,2) ,距离为 2 步。示例 3:
输入:maze = [[".","+"]], entrance = [0,0] 输出:-1 解释:这个迷宫中没有出口。
看了解题思路以后就很清晰了
从起点开始,按照上下左右四个方向访问邻居格子:
如果下标未越界:
- 非边界结点:加入访问队列,并标记已访问(即把maze改为墙)
- 边界节点:直接返回(因为距离是逐渐增大的,所以不用存储列表再找最小值)
class Solution(object):
def nearestExit(self, maze, entrance):
"""
:type maze: List[List[str]]
:type entrance: List[int]
:rtype: int
"""
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] # 右 下 左 上
width = len(maze[0])
height = len(maze)
start_y , start_x = entrance
maze[start_y][start_x] = '+'
queue = deque([(start_y, start_x, 0)])
while queue:
y, x, dis = queue.popleft()
for i in directions:
dir_y, dir_x = i
new_y = y + dir_y
new_x = x + dir_x
if 0 <= new_y < height and 0 <= new_x < width and maze[new_y][new_x] == '.':
# 边界空格子
if new_y == height - 1 or new_x == width - 1 or new_x == 0 or new_y == 0:
return dis + 1
else:
maze[new_y][new_x] = '+' # 一定别忘了 防止重复访问
queue.append((new_y, new_x, dis + 1))
return -1