拓扑排序(解决具有依赖性关系的问题)

拓扑排序是对一个有向图的顶点进行排序。它关心的是图中各个顶点的连接关系,这种连接关系也叫拓扑关系,因为它不关心各个顶点的位置与距离。

应用:

在一个有向无回路图中,要求对所有的节点进行排序。

先统计所有节点的入度,对于入度为0的节点就可以分离出来,然后把这个节点关联的节点的入度减一。

一直做改操作,直到所有的节点都被分离出来。

如果最后不存在入度为0的节点,那就说明有环,不存在拓扑排序,也就是很多题目的无解的情况。

下面是演示过程。

在这里插入图片描述
举例:力扣113 课程顺序
在这里插入图片描述
解题思路:

由题目给出一个有向无回路图,才能使得有可能的结果输出,图中任意两个点要么有先后关系,要么无关,
那么我们可以发现入度为0的点就是最先应该选修的课程,也就是我们的基础课程,其次修完这批课后,所有跟这些点关联的点入度减一,再在剩余的课中找出
基础课程,如此类推即可找出选课顺序,我们可以考虑用哈希表记录依赖关系,用数组记录每个点的入读,同时用队列维护入度为0的点

class Solution {
    public int[] findOrder(int numCourses, int[][] prerequisites) {
    Map<Integer,List<Integer>> map=new HashMap<>();//记录指向关系
    int []indeg=new int[numCourses];//记录每个点的入度
    for(int i=0;i<prerequisites.length;i++){
        List<Integer> list=map.getOrDefault(prerequisites[i][1],new ArrayList<>());
        list.add(prerequisites[i][0]);
        map.put(prerequisites[i][1],list);
        indeg[prerequisites[i][0]]++;
    }
    Queue<Integer> q=new LinkedList<>();
    for(int i=0;i<numCourses;i++){
        if(indeg[i]==0)
        q.offer(i);
    }
    int idx=0;
    int []ans=new int[numCourses];
    while(!q.isEmpty()){
        int top=q.poll();
        ans[idx]=top;
        idx++;
         List<Integer> list=map.getOrDefault(top,new ArrayList<>());
        for(int i=0;i<list.size();i++){
            int ch=list.get(i);
           indeg[ch]--;
           if(indeg[ch]==0){
            q.offer(ch);
           } 
        }
    }
    if(idx<numCourses)return new int[]{};
    return ans;
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
拓扑排序是用于有向无图(DAG, Directed Acyclic Graph)节点排序的一种算法,它确保了所有依赖关系都得到满足后,每个节点才会被访问。算法的主要目的是确定一个线性的序列,其的每一个节点都在其所有前驱节点之后。 拓扑排序的基本算法复杂度分析如下: 1. 时间复杂度(Time Complexity): - 最优情况(Best Case):如果输入图已经是线性的,即没有拓扑排序可以在一次遍历完成,时间复杂度为 O(V+E),其 V 是顶点数,E 是边数。这是因为每次迭代都可以确定一个节点的位置,不需要回溯。 - 平均情况(Average Case):在一般的有向无,算法的时间复杂度仍然是线性的,因为仍然是一次遍历,但可能无法确定是否为最优情况。 - 最坏情况(Worst Case):最坏情况发生在存在,但的节点恰好构成一个回路,这时算法需要进行多次迭代才能确定正确的顺序,导致复杂度退化到 O(VE),因为每增加一个节点,最多需要遍历整个图。 2. 空间复杂度(Space Complexity): - 常数空间:基本的拓扑排序算法使用常数额外空间来存储前驱节点集合,因此空间复杂度为 O(1)。 - 较大空间:如果采用深度优先搜索(DFS)或递归方法,可能会需要一个栈来保存递归调用,此时空间复杂度为 O(V)(最大递归深度等于V,最坏情况下),但这通常不是标准的拓扑排序算法的首选实现。 需要注意的是,拓扑排序不是所有的图都有解,对于有的有向图,它会返回“无解”,这就涉及到了算法的正确性和完整性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值