携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第23天,点击查看活动详情
前言
- leetcode hot100,是大厂面试高频题,也是必刷算法题。精选了100道LeetCode上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,按照官方说的,熟练掌握这 100 道题,就具备了代码世界通行的基本能力。
leetcode399题(除法求值)
本文来讲hot100第399题# 除法求值,本题有多种解法,图、二维数组 + 哈希表、并查集,掌握一种即可。
[["a","c"],["b","a"],["a","e"],["a","a"],["x","x"]]
给你一个变量对数组 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 的情况,且不存在任何矛盾的结果。
示例:
输入: 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 ]
提示:
1 <= equations.length <= 20equations[i].length == 21 <= Ai.length, Bi.length <= 5values.length == equations.length0.0 < values[i] <= 20.01 <= queries.length <= 20queries[i].length == 21 <= Cj.length, Dj.length <= 5Ai, Bi, Cj, Dj由小写英文字母与数字组成
分析
-
题目很长,先把题目意思分析出来,我们由题目可知
values[i] = Ai / Bi,这里的Ai/Bi是equations中的每一项的第一位和第二位 -
queries[j] = [Cj,Dj], 然后根据上面的条件求Cj / Dj -
无法确定答案或给定了已知条件中没有出现的字符串,返回-1.0
-
再看例子
equations = [["a","b"],["b","c"]]
values = [2.0,3.0]
queries = [["a","c"],["b","a"],["a","e"],["a","a"],["x","x"]]
a / b = 2, b / c = 3,a是b的两倍,b是c的三倍,所以a是c的 2 * 3 = 6倍- 所以
queries: [a/c = 6.0, b / 2 = 0.5, a / e = -1.0, a/a = 1, x/x = -1.0]
思路
- 先介绍下图算法:
- 图算法指利用特制的线条算图求得答案的一种简便算法。无向图、有向图和网络能运用很多常用的图算法,这些算法包括:各种遍历算法(这些遍历类似于树的遍历),寻找最短路径的算法,寻找网络中最低代价路径的算法,回答一些简单相关问题(例如,图是否是连通的,图中两个顶点间的最短路径是什么,等等)的算法。图算法可应用到多种场合,例如:优化管道、路由表、快递服务、通信网站等。
- 我们创建一个变量名为
grah的二维数组,表示图,grah[x][y]表示x / y的商 - 由例子可知,因为
grah[a][b] = 2, 所以grah[b][a] = 1 / 2, 因为grah[b][c] = 3, 所以grah[c][b] = 1 / 3 - 我们的题目要求
queries,所以此例子我们唯一不知道的就是grah[c][a] - 根据图算法,因为我们知道
a和b,b和c的关系,所以求c-a只要累乘c-b-a即可,C → B → A = grah[c][b] * grah[b][a] = 1 / 3 * 1 / 2 = 1 / 6
代码
var calcEquation = function (equations, values, queries) {
const grah = Object.create(null)
// 第一步,我们需要存储已知节点的路径值
for (let i = 0; i < values.length; i++) {
const x = equations[i][0], y = [equations[i][1]], value = values[i]
if (!grah[x]) grah[x] = Object.create(null)
grah[x][y] = value
if (!grah[y]) grah[y] = Object.create(null)
grah[y][x] = 1 / value
}
// 第二步,通过已知路径,求值
const visited = new Set()
const getVal = ([x, y]) => {
// 未找到x值 返回-1
if (!grah[x]) return -1
// 找到对应路径,返回目标结果
if (grah[x][y]) return grah[x][y]
// 找到x值,然后我们遍历查找路径,比如c-a,我们就找c-b-a
// 获取grah[x]所有的值
let kList = Object.keys(grah[x]), i = -1
// 遍历当前x对应的所有k,也就是当前节点对应的所有有值的节点
while (++i < kList.length) {
const k = kList[i]
// 使用set,防止我们重复查找
if (!visited.has(k)) {
visited.add(k)
// 查找grah[k, y]的值
const t = getVal([k, y])
visited.delete(k)
// 累乘
if (t !== -1) return grah[x][k] * t
}
}
// 之前没有return, 说明y也没有找到
return - 1
}
return queries.map(item => getVal(item))
};
结语
- 本题有多种解法,图、二维数组 + 哈希表、并查集,掌握一种即可,本文主要是图算法的应用,需要有一些图算法的基础。