力扣面试150题--除法求值

Day 62

题目描述

做法

此题本质是一个图论问题,对于两个字母相除是否存在值,其实就是判断,从一个字母能否通过其他字母到达,做法如下:

  1. 遍历所有等式,为每个变量分配唯一的整数索引。
  2. 初始化一个二维数组 graph,其中 graph[i][j] 表示变量 i 除以变量 j 的比值。
  3. 对于每个等式 a/b = v,设置 graph[a][b] = v 和 graph[b][a] = 1/v。
  4. 每个变量自身的比值为 1.0,即 graph[i][i] = 1.0。
  5. 对于每个查询 a/b,检查变量是否存在于映射中。如果存在,使用 DFS 查找从 a 到 b 的路径,并计算路径上的比值乘积。如果路径不存在,返回 -1.0。
java 复制代码
class Solution {
    public double find(double[][] graph, int x, int y, boolean[] visited) {//判断x到y是否可达
        if (graph[x][y] != 0) {
            return graph[x][y];//直接可达
        }
        visited[x] = true;
        for (int i = 0; i < graph.length; i++) {
            if (graph[x][i] != 0 && !visited[i]) {
                double p = find(graph, i, y, visited);
                if (p != 0.0) {
                    return p * graph[x][i];
                }
            }
        }
        return 0;
    }

    public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
        Map<String, Integer> num = new HashMap<>();//字符串到数字序号的转换
        int x = 0, y = 0;
        String a, b;
        for (int i = 0; i < equations.size(); i++) {
            a = equations.get(i).get(0);
            b = equations.get(i).get(1);
            if (!num.containsKey(a)) {
                num.put(a, x);
                x++;
            }
            if (!num.containsKey(b)) {
                num.put(b, x);
                x++;
            }
        }
        double[][] graph = new double[x][x];
        for (int i = 0; i < equations.size(); i++) {
            a = equations.get(i).get(0);
            b = equations.get(i).get(1);
            x = num.get(a);
            y = num.get(b);
            graph[x][y] = values[i];//x/y
            graph[y][x] = 1 / values[i];//y/x
        }
        for (int i = 0; i < graph.length; i++) {
            graph[i][i] = 1.0;//对角线全为1
        }
        //图初始化结束
        double[] res = new double[queries.size()]; //结果集合
        double sum = 0.0;
        for (int i = 0; i < queries.size(); i++) {
            a = queries.get(i).get(0);
            b = queries.get(i).get(1);
            if (!num.containsKey(a) || !num.containsKey(b)) {
                res[i] = -1.0;
                continue;
            }
            x = num.get(a);
            y = num.get(b);
            boolean[] visited = new boolean[graph.length];
            sum = find(graph, x, y, visited);//判断x到y是否可达
            if (sum == 0) {
                //不可达
                sum = -1.00000;
            }
            res[i] = sum;
            sum = 0.0;
        }
        return res;
    }
}
相关推荐
AI成长日志38 分钟前
【笔面试算法学习专栏】哈希表基础:两数之和与字母异位词分组
学习·算法·面试
abant21 小时前
leetcode 239 单调队列 需要一些记忆
算法·leetcode·职场和发展
漫霂1 小时前
二叉树的统一迭代遍历
java·算法
炽烈小老头1 小时前
【每天学习一点算法 2026/04/08】阶乘后的零
学习·算法
Mr_Xuhhh1 小时前
算法刷题笔记:从滑动窗口到哈夫曼编码,我的算法进阶之路
开发语言·算法
MicroTech20251 小时前
突破虚时演化非酉限制:MLGO微算法科技发布可在现有量子计算机运行的变分量子模拟技术
科技·算法·量子计算
ShineWinsu1 小时前
对于Linux:文件操作以及文件IO的解析
linux·c++·面试·笔试·io·shell·文件操作
hssfscv1 小时前
软件设计师下午题六——Java的各种设计模式
java·算法·设计模式
珂朵莉MM1 小时前
第七届全球校园人工智能算法精英大赛-算法巅峰赛产业命题赛第3赛季优化题--多策略混合算法
人工智能·算法
罗西的思考2 小时前
【OpenClaw】通过 Nanobot 源码学习架构---(6)Skills
人工智能·深度学习·算法