首页 > 其他分享 >每日一题: 2192. 有向无环图中一个节点的所有祖先

每日一题: 2192. 有向无环图中一个节点的所有祖先

时间:2024-04-04 16:12:29浏览次数:24  
标签:int edges 环图 2192 vector 祖先 ans 节点

给你一个正整数 n ,它表示一个 有向无环图 中节点的数目,节点编号为 0 到 n - 1 (包括两者)。

给你一个二维整数数组 edges ,其中 edges[i] = [fromi, toi] 表示图中一条从 fromi 到 toi 的单向边。

请你返回一个数组 answer,其中 answer[i]是第 i 个节点的所有 祖先 ,这些祖先节点 升序 排序。

如果 u 通过一系列边,能够到达 v ,那么我们称节点 u 是节点 v 的 祖先 节点。

示例 1:

输入:n = 8, edgeList = [[0,3],[0,4],[1,3],[2,4],[2,7],[3,5],[3,6],[3,7],[4,6]]
输出:[[],[],[],[0,1],[0,2],[0,1,3],[0,1,2,3,4],[0,1,2,3]]
解释:
上图为输入所对应的图。
- 节点 0 ,1 和 2 没有任何祖先。
- 节点 3 有 2 个祖先 0 和 1 。
- 节点 4 有 2 个祖先 0 和 2 。
- 节点 5 有 3 个祖先 0 ,1 和 3 。
- 节点 6 有 5 个祖先 0 ,1 ,2 ,3 和 4 。
- 节点 7 有 4 个祖先 0 ,1 ,2 和 3 。

本题是一个图论问题,本质是拓扑排序,我还以为要用并查集来做,事实上这个思路是不完全正确的。该问题必须用已知答案来推出未知答案,而我最开始默认0一定是入度为0的点,即父节点是确定的(没有父节点),但通过样例发现并非这样,因此就陷入如何选择起点的问题,当我试图再找一个入度为0的点作为起点时,发现仅靠发现一个起点并不能解决所有问题,因为无论从哪里出发,我的思路都不能保证递归做合并父节点集合的时候父节点集合是确定的,因此也只是通过了部分样例。

class Solution {
public:
    void merge(const vector<vector<int>>& fa,set<int>& son,int index){    //将查找i节点的父节点
        son.insert(index);
        for(int i:fa[index]){
            son.insert(i);
            merge(fa,son,i);
        }
    }
    void print(const set<int>& tmp,vector<int>& result){                //将集合set并入对应i节点的父节点集合
        for(int i:tmp)result.push_back(i);
    }                                        
    vector<vector<int>> getAncestors(int n, vector<vector<int>>& edges) {
        vector<vector<int>> result(n);
        int start=0;
        for(int k=0;k<n;k++){                                        //尝试寻找一个入度为0的作为起点
            int flag=0;
            for(int i=0;i<edges.size();i++)if(edges[i][1]==k){flag=1;break;}
            if(!flag){
                start=k;break;
            }
        }
        set<int> tmp;
        int flag=1;
        for(int i=start;flag||i%n!=start;i+=1,i%=n){
            flag=0;
            for(int j=0;j<edges.size();j++){
                if(edges[j][1]==i)merge(result,tmp,edges[j][0]);
            }
            print(tmp,result[i]);
            tmp.clear();
        }
        return result;
    }
};

 正确做法,利用拓扑序列的思路,先处理入度为0的,然后是将处理过的“删除”,继续处理新的入度为0的节点:

class Solution {
public:
    vector<vector<int>> getAncestors(int n, vector<vector<int>>& edges) {
        vector<vector<int>> g(n, vector<int>());
        vector<set<int>> ans(n);
        vector<int> in(n, 0);
        for(auto e : edges){
            int x = e[0], y = e[1];
            g[x].push_back(y);
            in[y]++;
        }
        queue<int> q;
        for(int i = 0; i < n; i++){
            if(in[i] == 0) q.push(i);
        }
        while(!q.empty()){
            int u = q.front();
            q.pop();
            for(auto v : g[u]){
                ans[v].insert(u);
                for(auto x : ans[u]) ans[v].insert(x);
                if(--in[v] == 0) q.push(v);
            }
        }
        vector<vector<int>> res(n);
        for(int i = 0; i < n; i++) res[i] = vector<int>(ans[i].begin(), ans[i].end());
        return res;
    }
};

作者:实名吃香菜
链接:https://leetcode.cn/problems/all-ancestors-of-a-node-in-a-directed-acyclic-graph/solutions/2723576/tuo-bu-pai-xu-by-xinpengq-2132/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

标签:int,edges,环图,2192,vector,祖先,ans,节点
From: https://www.cnblogs.com/Liubox/p/18114263

相关文章

  • leetcode每日一题 1379. 找出克隆二叉树中的相同节点
    问题描述给你两棵二叉树,原始树original和克隆树cloned,以及一个位于原始树original中的目标节点target。其中,克隆树cloned是原始树original的一个副本。请找出在树cloned中,与target相同的节点,并返回对该节点的引用(在C/C++等有指针的语言中返回节点指针,其他......
  • zookeeper监听集群节点的实现zkclient组件实现方案(Java版)
    ZooKeeperWatcher机制client向zookeeper注册监听client注册的同时会存储一个WatchManager对象向zookeeper发生改变则notificationclient并发送一个WatchManager对象,然后client再更新该对象packagecom.jacky.zk.demo;importorg.I0Itec.zkclient.IZkChildListen......
  • LeetCode-1379. 找出克隆二叉树中的相同节点【树 深度优先搜索 广度优先搜索 二叉树】
    LeetCode-1379.找出克隆二叉树中的相同节点【树深度优先搜索广度优先搜索二叉树】题目描述:解题思路一:递归,由于我们比较的是节点而不是节点值(例如C++比较的是地址),所以下面的代码也适用于树中有值相同节点的情况(本题的进阶问题)。解题思路二:递归这题有几个关键点,一:判......
  • AWS通过交换机连接管理节点检查AWS云状态
    1、ceph集群检查要查看Ceph集群的状态,可以使用Ceph的命令行工具ceph。以下是一个基本的命令,它将提供Ceph集群的概览状态,包括集群的健康状况、OSD数量、PG状态等:ceph-s#这个命令会输出一个详细的状态报告,其中包括了集群的各种资源和服务的状态。cephosdtree|grep-E'host|......
  • system.text.json 搜索获取节点值
    搜索Json节点值publicstaticclassJsonStringExtensions{publicstaticboolTryGetNestValueByJsonKey(thisstringjsonString,stringkey,outstringres){res=string.Empty;try{vararr=key.Split('.');......
  • KingbaseES V8R6集群运维案例之---备节点恢复为单实例库
    KingbaseESV8R6集群运维案例之---备节点恢复为单实例库案例说明:在生产环境中,手工将集群节点恢复为单实例节点,操作可以分为两步。第一步,先将节点从repmgr管理中注销,脱离集群的管理;第二步,从流复制中拆分节点,成为单实例节点。适用版本:KingbaseESV8R6集群架构:ID......
  • 2024.2.7力扣每日一题——二叉树的堂兄弟节点2
    2024.2.7题目来源我的题解方法一哈希表+层序遍历(自己的想法,硬在每一层去算)方法二广度优先遍历(官方题解,在上一层求下一层)题目来源力扣每日一题;题序:2461我的题解方法一哈希表+层序遍历(自己的想法,硬在每一层去算)使用两个哈希表分别映射parent<子节点,父节点>,c......
  • 2024.2.8力扣每日一题——二叉树的堂兄弟节点
    2024.2.8题目来源我的题解方法一层序遍历方法二深度优先遍历题目来源力扣每日一题;题序:993我的题解方法一层序遍历使用层序遍历,先判断x或y是否是根节点,若是则x和y必然不可能是堂兄弟节点。每次遍历当前层时判断下一层是否出现x和y,若x和y分别出现在该节点的......
  • DOM 节点遍历:掌握遍历 XML文档结构和内容的技巧
    遍历是指通过或遍历节点树遍历节点树通常,您想要循环一个XML文档,例如:当您想要提取每个元素的值时。这被称为"遍历节点树"。下面的示例循环遍历所有<book>的子节点,并显示它们的名称和值:<!DOCTYPEhtml><html><body><pid="demo"></p><script>varx,i,xmlDoc;va......
  • 图的广度优先遍历BFS得到各节点的度
    难题初始化,在下面的代码中,我们创建了一个具有十个结点的图结构,并且通过rand函数来给各结点之间的路径赋值。typedefstructGraph{//创建图结构 intvalues[10][10];//图结构的邻接矩阵,权值为0意味两结点无路径}Graph;voidFillGraph(Graph&g)......