中级农民
- 积分
- 112
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2018-11-14
- 最后登录
- 1970-1-1
|
Leetcode 399 Evaluate Division
这道题呢在很多咕咕的面试中出现过变种,比如汇率转换,但本质就是这道题。
我比较喜欢Union Find,并且这道题union find的时间复杂度相比较起DFS来说要小。
首先思路是这样的,我们需要把信息包装成一个node的形式,这样比较方便。node里面包含它的parent和它到parent的距离。
然后我们需要一个hashmap,用来通过string获取我们封装好的node。比如我们在这道题中就是变量“a”,"b"之类的string 来获取相应的node。
接着就是实现unionfind的基本函数find 和 union。
find:output是parent node,input是变量名。首先查看这个变量在不在map里,如果不在,则不存在,就更不用说find parent了。直接return null。如果在map里,检查一下这个node的parent是不是自己,如果是,则直接返回自己。说明这个node是root。
如果不是的话,就再call这个find(node.parent)。这个会返回parent node,再把一开始的node的parent设定为这个找到的parent,然后distance再乘上到parent的distance。
union就更多case了。如果两个变量都没有在map里,就直接创建两个node,然后把第一个变量的node的parent设置为第二个变量node,距离为给定的value。第二个变量的parent设为自己,距离为1.0
然后如果第一个变量在map中,第二个不在,则把第二个变量node的parent设为第一个,然后距离是1/value
如果是第二个变量在map中,第一个不在,则把第一个node的parent设为第二个,距离是value。
最后一种情况是两个变量都在map中,这意味着两个变量是disconnected graph,现在我们要链接起来。首先找到他们分别的root,然后如果这两个root不是一样的话,将第一个parent设为第二个,然后距离设为给定value * 第二个变量node的距离。这里的意思是,首先我们从第一个变量连接到第二个变量,再从第二个变量走到他的parent。这样就相当于完成第一个变量到parent。
最后iterate一遍query,如果都能找到parent,返回第一个变量距离/第二个变量距离。
否则返回-1、
- class Solution {
- class Node {
- public String parent;
- public double ratio;
- public Node(String parent, double ratio) {
- this.parent = parent;
- this.ratio = ratio;
- }
- }
-
- class UnionFindSet {
- private Map<String, Node> parents = new HashMap<>();
-
- public Node find(String s) {
- if (!parents.containsKey(s)) return null;
- Node n = parents.get(s);
- if (!n.parent.equals(s)) {
- Node p = find(n.parent);
- n.parent = p.parent;
- n.ratio *= p.ratio;
- }
- return n;
- }
-
- public void union(String s, String p, double ratio) {
- boolean hasS = parents.containsKey(s);
- boolean hasP = parents.containsKey(p);
- if (!hasS && !hasP) {
- parents.put(s, new Node(p, ratio));
- parents.put(p, new Node(p, 1.0));
- } else if (!hasP) {
- parents.put(p, new Node(s, 1.0 / ratio));
- } else if (!hasS) {
- parents.put(s, new Node(p, ratio));
- } else {
-
- Node rS = find(s);
- Node rP = find(p);
- if(rS != rP)
- {
- rS.parent = rP.parent;
- rS.ratio = ratio * rP.ratio;
- }
- }
- }
- }
-
- public double[] calcEquation(String[][] equations, double[] values, String[][] queries) {
- UnionFindSet u = new UnionFindSet();
-
- for (int i = 0; i < equations.length; ++i)
- u.union(equations[i][0], equations[i][1], values[i]);
-
- double[] ans = new double[queries.length];
-
- for (int i = 0; i < queries.length; ++i) {
- Node rx = u.find(queries[i][0]);
- Node ry = u.find(queries[i][1]);
- if (rx == null || ry == null || !rx.parent.equals(ry.parent))
- ans[i] = -1.0;
- else
- ans[i] = rx.ratio / ry.ratio;
- }
-
- return ans;
- }
- }
复制代码 |
|