首页 > 其他分享 >Leetcode(剑指offer专项训练)——DFS/BFS专项(1)

Leetcode(剑指offer专项训练)——DFS/BFS专项(1)

时间:2023-04-08 14:55:06浏览次数:43  
标签:node index 专项 offer graph cnt DFS vector mp

计算除法

题目

给定一个变量对数组 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 替代这个答案。
链接

题解

可以将题目理解为是给定了一张图,找到起点到终点的路径的问题;
比如给的示例中

输入: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 ]

其中已知a/b以及b/c,则a/c=(a/b)*(b/c);可以等价于当我们知道有向图a➡b以及b➡c的边权时候,a➡c的边权也就知道了(按照题目中的意思为边权乘积)
接着要做的就是将字符串视作图的节点(用map记录),除法的值视作两个节点有向图的边权(用graph记录),而为了避免同一个有向边反复遍历dfs陷入死循环,需要有vis来记录每一组中某个有向边是否被使用过
所以题目的意思可以抽象为给一个有向图以及一组起始点,找到起点到终点的路径并给出路径边的乘积

答案如下:

class Solution {
public:
    double path;
    void dfs(int node_index,int ed,vector<vector<double>>&graph,vector<vector<int>>&vis,double temp,int flag){
        //printf("%d %lf\n",node_index,temp);
        if(node_index==ed){
            path=temp;
        }else{
            for(int next_node_index=0;next_node_index<graph[node_index].size();next_node_index++){
                if(vis[node_index][next_node_index]<flag&&graph[node_index][next_node_index]>0){
                    vis[node_index][next_node_index]=flag;
                    dfs(next_node_index,ed,graph,vis,temp*graph[node_index][next_node_index],flag);
                }
            }
        }
    }
    vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
        unordered_map<string,int>mp;
        int cnt=0;//统计节点个数
        for(auto eq:equations){
            if(mp.find(eq[0])==mp.end()){
                mp[eq[0]]=cnt;
                cnt++;
            }
            if(mp.find(eq[1])==mp.end()){
                mp[eq[1]]=cnt;
                cnt++;
            }
        }
        vector<vector<double>>graph(cnt,vector<double>(cnt,-1));
        vector<vector<int>>vis(cnt,vector<int>(cnt,0));
        for(int i=0;i<values.size();i++){
            int u=mp[equations[i][0]];
            int v=mp[equations[i][1]];
            graph[u][v]=values[i];
            graph[v][u]=1/values[i];
        }

        int n=queries.size();
        vector<double>ans(n);
        int i=0;
        for(auto q:queries){
            //printf("======\n");
            if(mp.find(q[0])!=mp.end()&&mp.find(q[1])!=mp.end()){
                if(graph[mp[q[0]]][mp[q[1]]]!=-1){
                    ans[i]=graph[mp[q[0]]][mp[q[1]]];
                }else{
                    path=-1;
                    dfs(mp[q[0]],mp[q[1]],graph,vis,1,i+1);
                    if(path!=-1){
                        graph[mp[q[0]]][mp[q[1]]]=path;
                        if(path!=0){
                            graph[mp[q[1]]][mp[q[0]]]=1.0/path;
                        }
                    }
                    ans[i]=path;
                }
                
            }else{
                ans[i]=-1;
            }
            i++;

            // a / b=2; b/c =3
            // b / a

        }
        return ans;
    }
};

标签:node,index,专项,offer,graph,cnt,DFS,vector,mp
From: https://www.cnblogs.com/SaltyCheese/p/17298557.html

相关文章

  • 剑指offer66(Java)-构建乘积数组(中等)
    题目:给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中 B[i]的值是数组A中除了下标i以外的元素的积,即 B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。 示例:输入:[1,2,3,4,5]输出:[120,60,40,30,24] 提示:所有元素乘积之和不会......
  • 剑指offer03(Java)-数组中重复的数字(简单)
    题目:找出数组中重复的数字。在一个长度为n的数组nums里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。示例1:输入:[2,3,1,0,2,5,3]输出:2或3 限制:2<=n<=1000......
  • 剑指 Offer 16. 数值的整数次方
    题解链接:剑指Offer16.数值的整数次方方法一:迭代实现快速幂解题思路通过迭代的方法,自下向上实现快速幂求解过程,初始化结果\(res=1\),底数\(t=x\),幂次为\(n\)。当\(n\)为奇数时,\(res=res*t\),先乘上一个\(t\),此时还有\(n-1\)个\(t\)相乘,即相当于计算\((t*......
  • 剑指 Offer 15. 二进制中1的个数
    题目链接:剑指Offer15.二进制中1的个数方法一:位运算解题思路x=n&-n,\(x\)表示\(n\)的最后一位\(1\)所对应的值,每减去一次\(x\),相当于有一个\(1\),\(res++\)。代码classSolution{public:inthammingWeight(uint32_tn){intres=0;w......
  • 用 Go 剑指 Offer 29. 顺时针打印矩阵
    给你一个m行n列的矩阵 matrix,请按照顺时针螺旋顺序,返回矩阵中的所有元素。 示例1:  输入:matrix=[[1,2,3],[4,5,6],[7,8,9]]输出:[1,2,3,6,9,8,7,4,5]示例2:  输入:matrix=[[1,2,3,4],[5,6,7,8],[9,10,11,12]]输出:[1,2,3,4,8,12,11,10,9,5,6,7] 提示:m......
  • 一个人的职业生涯之旅 —— 应届生求职、面试、Offer、跳槽(发展瓶颈、薪资倒挂、职业
    一、应届生求职问题1、求职平台1、Boss直聘2、前程无忧3、拉勾网4、应届生求职网站_最新更新校园招聘/实习机会/内推资讯_牛客网_牛客网_牛客网2、简历怎么写2.1、简历照片1、要与本人形象相符,不要看上去有较大差别,使用最近半年内的免冠照片,选择能够显示自己气质佳的照片,但......
  • 用 Go 剑指 Offer 17. 打印从1到最大的n位数
    输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数999。示例1:输入:n=1输出:[1,2,3,4,5,6,7,8,9] 说明:用返回一个整数列表来代替打印n为正整数通过次数251,223提交次数323,027来源:力扣(LeetCode)链接:https://leetcod......
  • 用 Go 剑指 Offer 11. 旋转数组的最小数字
    已知一个长度为n的数组,预先按照升序排列,经由1到n次旋转后,得到输入数组。例如,原数组nums=[0,1,4,4,5,6,7]在变化后可能得到:若旋转4次,则可以得到[4,5,6,7,0,1,4]若旋转7次,则可以得到[0,1,4,4,5,6,7]注意,数组[a[0],a[1],a[2],...,a[n-1]]旋转一次的结果为数......
  • 剑指offer004(Java)-只出现一次的数字(中等)
    题目:给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次。请你找出并返回那个只出现了一次的元素。示例1:输入:nums=[2,2,3,2]输出:3示例2:输入:nums=[0,1,0,1,0,1,100]输出:100 提示:1<=nums.length<=3*104-231<=nums[i]<=231-......
  • HDFS存储介绍
    1:datanode数据节点-存放数据的2:namenode 名字节点-主要是存放元数据的,比如:文件大小 名称存放位置等3:secondarynamenode是存放fimage信息的,具体解释如下:namenode   fimage   editlognamenode中每次有信息变化的时候,都会放到editlog中,然后由editlog同步......