leetcode207.课程表与拓扑排序

一、拓扑排序
百度百科:对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。

简单讲就是,在一个排序中,某些元素的存在依赖于另外的元素。或者说某些元素必须排在另外的元素后面。
比如说,穿衣服的时候,必须先穿裤衩,再穿秋裤,然后是棉裤和套在最外层的运动裤。而上身的背心和裤衩则没有依赖关系。
在这里插入图片描述二、拓扑排序的实现
1.广度优先
简单来讲,就是始终把每次将入度为0的顶点去掉。
在这里插入图片描述
所以排序的结果就是[1,2,3,4,5]或者[1,2,4,3,5]。这个图就是有向无环图。

2.深度优先
从1开始,1->2->3->5或者1->2->4->5或者1->4->5
所以排序结果就是[1,2,3,4,5]或者[1,2,4,3,5]。这个图是一个有向无环图。

三、leetcode 207.课程表与拓扑排序
1.典型的拓扑排序题。因为如果要学习B课程,就必须要先学习A课程。
按广度优先来做:
2.建立一个邻接矩阵、一个入度表和一个队列。邻接矩阵的建立方法:二维的动态数组。数组的行是起始顶点,数组的列是到达顶点。入度表就按技术排序的方法。
在这里插入图片描述
3.如果一个数字的入度为0,就把它存到队列中。之后把队列中的数出队,同时将原数组长度-1,自然也将该数字的邻接数的入度-1。
4.如果此时邻接数有入度为0的,就继续放入队列,然后循环执行第三步,直到队列中为空。
5.此时,如果数组长度没有减到0,说明有入度不为0的数,意味着是图是有环的。如果数组长度减到0了,说明没有环,可以按照一定的顺序将数组中的数全部遍历完。
6.代码如下:

class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        int[] indegress = new int[numCourses];
        List<List<Integer>> adjency = new ArrayList<>();
        Queue<Integer> queue = new LinkedList<>();
        for(int i=0;i<numCourses;i++){
            adjency.add(new ArrayList<>());
        }
        for(int[] cp:prerequisites){
            indegress[cp[0]]++;
            adjency.get(cp[1]).add(cp[0]);
        }
        for(int i=0;i<numCourses;i++){
            if(indegress[i]==0)queue.offer(i);
        }
        while(!queue.isEmpty()){
            int pre = queue.poll();
            numCourses--;
            for(int cur:adjency.get(pre))
            if(--indegress[cur] == 0) queue.add(cur);
        }
        return numCourses==0;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值