399. 除法求值

整体的思路是:

  1. 根据equations建图,首先找节点,将每个字母映射成数字,映射关系如map所示
  2. 然后根据equations找边,并赋值
  3. 使用Floyd算法算出每两个节点之间的距离
  4. 遍历queries得到每组字符之间的距离
class Solution {
    public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
        int nvars = 0;
        HashMap<String, Integer> map = new HashMap<>();
        
        int n = equations.size();
        for (int i = 0; i < n; ++i) {
            if (!map.containsKey((equations.get(i)).get(0))) {
                map.put((equations.get(i)).get(0), nvars++);
            }
            if (!map.containsKey((equations.get(i)).get(1))) {
                map.put((equations.get(i)).get(1), nvars++);
            }
        }

        double[][] d = new double[nvars][nvars];
        for (int i = 0; i < nvars; ++i) {
            Arrays.fill(d[i], -1.0);
        }
        for (int i = 0; i < n; ++i) {
            int va = map.get((equations.get(i)).get(0)), vb = map.get((equations.get(i)).get(1));
            d[va][vb] = values[i];
            d[vb][va] = 1.0 / values[i];
        }

        for (int k = 0; k < nvars; ++k) {
            for (int i = 0; i < nvars; ++i) {
                for (int j = 0; j < nvars; ++j) {
                    if (d[i][k] > 1e-6 && d[k][j] > 1e-6) { // 这里注意精度
                        d[i][j] = d[i][k] * d[k][j];
                    }
                }
            }
        }

        int q_size = queries.size();
        double[] res = new double[q_size];
        for (int i = 0; i < q_size; ++i) {
            double result = -1.0;
            if (map.containsKey((queries.get(i)).get(0)) && map.containsKey((queries.get(i)).get(1))) {
                int a = map.get((queries.get(i)).get(0)), b = map.get((queries.get(i)).get(1));
                if (d[a][b] > 0) result = d[a][b];
            }
            res[i] = result;
        }
        return res;
    }
}

这里要注意精度问题,在官方提交中,如果d[i][j]>0则无法通过28用例,如图所示。
399. 除法求值_第1张图片
因此根据题目的精度要求,两点之间最小距离为0.00001时可以,但是更大就不行了,因此把精度控制在0.000001

你可能感兴趣的:(LeetCode,算法,leetcode)