题目描述与分析
给出一个以邻接矩阵表示的有向图,实现一个判断其拓扑排序是否唯一的函数
拓扑排序首次考代码大题。在 408 算法大题中,由于不可以使用 STL,因此要用一个容量很大的数列去模拟队列。但是思考本题后发现,如果一个图的拓扑排序是唯一的,那么它的辅助队列的任何时刻,容量都不超过 1,否则在下一轮输出时可以任选队列中的一个输出,从而造成拓扑排序不唯一。基于这个原理,且考虑到图的节点编号非负,那么可以用一个 int 型变量模拟队列,其值为 -1 表示队列为空,否则其值就是队列中的唯一元素。该方法实现了最优空间复杂度,避免了用数组模拟队列的麻烦。类似的优化思路还有,如果语言中没有 Pair
类似的实现,但是想使用一个 int 类型的二元组,可考虑用一个 long 变量进行模拟,高 32 位和低 32 位存储两个 int,取出和放入时使用相应的掩码 AND 运算即可
特别注意的是,根据题意,如果图中不存在拓扑排序,我们也应返回 -1
答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| int unique(vector<vector<int>> &graph) { int queue = -1; int num = 0; int n = graph.size(); int inDegree[n]; for (int i = 0; i < n; i++) { inDegree[i] = 0; } for (int i = 0; i < n; i++) { int degree = 0; for (int j = 0; j < n; j++) { if (graph[j][i] != 0) { degree++; } } if (degree == 0) { if (queue != -1) { return -1; } queue = i; } } while (queue != -1) { int cur = queue; num++; queue = -1; for (int i = 0; i < n; i++) { if (graph[cur][i] != 0) { graph[cur][i] = 0; inDegree[i]--; if (inDegree[i] == 0) { if (queue != -1) { return -1; } queue = i; } } } } if (num != n) { return -1; } return 1; }
|