(Leetcode)判断一个图是否是可以拓扑排序的——使用Queue
来源:互联网 发布:北大mba课程书籍 知乎 编辑:程序博客网 时间:2024/05/22 00:44
207. Course Schedule
拓扑排序 Topological Order
对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。
通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。
简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。
There are a total of n courses you have to take, labeled from 0 to n - 1.
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?
For example:
2, [[1,0]]
There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.
2, [[1,0],[0,1]]
There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.
分析
- 通过计算所有点的inDegree(入度),找到拓扑序列中可能是开头的点(inDegree[node]==0)。将这些点加入队列queue。
- 遍历队列,对每一个队列中的点cur_node:
找到他的一个post_node,并将inDegree[post_node]- -
如果inDegree[post_node]==0 ,把post_node也加入队列。 - 遍历所有inDegree,如果inDegree[node]!=0。说明图中有环,说明有node没有被加入queue。
(那只可能是因为这个node在他的pre_node还没被访问到的时候,就被访问了。)
Code
public class Solution { public boolean canFinish(int numCourses, int[][] prerequisites) { if (numCourses <= 0) return false; Queue<Integer> queue = new LinkedList<Integer>(); //LinkedList实现了Queue接口 int inDegree[] = new int[numCourses]; for(int i=0; i<prerequisites.length; i++){ inDegree[prerequisites[i][1]]++; } for(int i=0; i<numCourses; i++){ if(inDegree[i]==0){// this node don't have prenode queue.offer(i); } } Integer curNode; while((curNode = (Integer)queue.poll())!=null){ for(int i=0; i<prerequisites.length; i++){ if(prerequisites[i][0]==curNode){ inDegree[prerequisites[i][1]]--; if(inDegree[prerequisites[i][1]]==0){ queue.offer(prerequisites[i][1]); } } } } for(int i=0; i<numCourses; i++){ if(inDegree[i]!=0) return false; } return true; }}
java Queue中 remove/poll, add/offer, element/peek区别
offer,add区别:
一些队列有大小限制,因此如果想在一个满的队列中加入一个新项,多出的项就会被拒绝。
这时新的 offer 方法就可以起作用了。它不是对调用 add() 方法抛出一个 unchecked 异常,而只是得到由 offer() 返回的 false。
poll,remove区别:
remove() 和 poll() 方法都是从队列中删除第一个元素。remove() 的行为与 Collection 接口的版本相似,
但是新的 poll() 方法在用空集合调用时不是抛出异常,只是返回 null。因此新的方法更适合容易出现异常条件的情况。
peek,element区别:
element() 和 peek() 用于在队列的头部查询元素。与 remove() 方法类似,在队列为空时, element() 抛出一个异常,而 peek() 返回 null
- (Leetcode)判断一个图是否是可以拓扑排序的——使用Queue
- 拓扑排序(判断是否是有向无环图)
- 判断有向图是否存在回路—拓扑排序
- [SDUT](2140)图结构练习——判断给定图是否存在合法拓扑序列 ---拓扑排序(图)
- 图结构练习——判断给定图是否存在合法拓扑序列(拓扑排序判断环)
- 拓扑排序(判断有向图是否有回路)
- 拓扑排序(判断有向图是否有回路)
- 拓扑排序(判断有向图是否有回路)
- leetcode的判断一个二叉树是否是平衡树
- 判断有向图是否存在环的2种方法(深度遍历,拓扑排序)
- leetcode palindrome-number(判断一个数字是否是回文)
- 判断一个自然数是否是某个数的平方。当然不能使用开方运算—谷歌
- 判断一个自然数是否是某个数的平方。当然不能使用开方运算—谷歌
- 判断有向图是否有环之拓扑排序-LeetCode 207. Course Schedule
- POJ——1308Is It A Tree?(模拟拓扑排序判断有向图是否为树)
- 拓扑排序——判断有向图是否存在回路
- 如何判断一个直播系统是否使用的是RTMP
- 写一个函数,判断一个int型的正整数是否是2的幂,即是否可以表示成2^X的形式(不可以用循环)
- 安卓中点击按钮变换颜色--实现更好的人机交互
- 套接字的三种类型
- 理解23种设计模式
- 权限控制器——Shiro安全框架
- 很好用的设置RecycleView的ItemDecoration的框架FlexibleDivider
- (Leetcode)判断一个图是否是可以拓扑排序的——使用Queue
- leetcode--jump_game&&jump_game_II
- UILocalNotification本地通知
- ubuntu sudo出现sudo:must be setuid root
- 分布式系统中的通讯范型与间接通信
- 实现广告条,采用ViewPager里嵌套fragment
- 流程控制
- java之物件导向程式设计(一)
- LINUX: 配置自己的网卡信息