Problem: 1557. 可以到达所有点的最少点数目
思路
所有入度为0的结点的数目即可以到达所有点的最少点数目
证明
首先,所有入度为0的结点是一定要选的,因为不可能从其它任何结点通过任何一条路径到达入度为0的结点。接下来,如果能证明总存在一个入度为0的结点通过某一条路径到达一个入度不为0的结点,那么我们的思路就是正确的。
反证法
假设有一个入度不为0的结点a,所有入度为0的结点都无法通过一条路径到达结点a。
因为a的入度不为0,那么至少有一条边从某一个结点出发并指向结点a。那么这个结点可以是什么呢?因为是有向无环图,所以不可以是a,又因为我们假设所有入度为0的结点都无法通过一条路径到达结点a,所以也不可以是入度为0的结点。那么这个结点只能是除结点a之外的任意一个入度不为0的结点,这里我们把这个结点叫做b。因为b的入度也不为0,考虑某一个结点c(有一条边从c出发到达b),同样因为是有向无环图,c不可能是a或b,又因为我们假设所有入度为0的结点都无法通过一条路径到达结点a,所以也不可以是入度为0的结点。那么这个结点只能是除结点a、b之外的任意一个入度不为0的结点。考虑最后一个入度不为0的结点d,考虑某一个结点x(有一条边从x出发到d),因为是有向无环图,所有x不能是a、b、c…,故x只能是某一个入度为0的结点,即存在一个入度为0的结点x通过x -> d -> … -> c -> b -> a这样一条路径到达结点a,与所有入度为0的结点都无法通过一条路径到达结点a假设相矛盾。故总存在一个入度为0的结点通过某一条路径到达一个入度不为0的结点。
证毕
解题方法
遍历所有的边集edges
,记录每个结点的入度。所有入度为0的结点的集合即为该题的答案。
复杂度
- 时间复杂度:
O ( n ) O(n) O(n)
- 空间复杂度:
O ( n ) O(n) O(n)
Code
class Solution {
public:
vector<int> findSmallestSetOfVertices(int n, vector<vector<int>>& edges) {
vector<int> indegree(n);
for (auto &i : edges) {
++indegree[i[1]];
}
vector<int> ret;
for (int i = 0; i < n; ++i) {
if (indegree[i] == 0) {
ret.push_back(i);
}
}
return ret;
}
};