一开始的做法是这样的:
class Solution {
public:
int findJudge(int N, vector<vector<int>>& trust) {
vector<int> sign(N+1, 0);//i有信任的人,则sign[i] = 1
vector<int> count(N+1, 0);//信任i的人的个数是count[i]
for(const auto &v : trust){
if(!sign[v[0]]) sign[v[0]] = 1;//v[0]有信任的人,必然是村民
++count[v[1]];
}
//属性1:如果有法官,那么他对应的值应该为0,而且只有他一个人对应的值为0
auto it = find(sign.begin()+1, sign.end(), 0);
if(it == sign.end()) return -1;//所有人都有信任的人
//对于法官,信任他的人数是N-1(属性2)
if(count[it-sign.begin()] == N-1) return it - sign.begin();
return -1;
}
};
如果用图的思想来考虑:
有向图问题。 并且法官实际上就是出度为0,入度为 N - 1的节点。
class Solution {
public:
int findJudge(int N, vector<vector<int>>& trust) {
vector<int> inDegree(N+1, 0);//信任 i 的人
vector<int> outDegree(N+1, 0);// i 信任的人
for(const auto &v : trust){
++inDegree[v[1]];
++outDegree[v[0]];
}
for(int i = 1; i <= N; ++i){
if(inDegree[i] == N-1 && outDegree[i] == 0) return i;
}
return -1;
}
};
一个数组也可以:
参考:【一个数组搞定】通俗易懂(997. 找到小镇的法官) - 找到小镇的法官 - 力扣(LeetCode)
法官是 入度 - 出度 == N - 1 的点,并且不是法官的人不可能是。
class Solution {
public:
int findJudge(int N, vector<vector<int>>& trust) {
vector<int> count(N+1, 0);//入度 - 出度的差值
for(const auto &v : trust){
++count[v[1]];
--count[v[0]];//v[0]指向一个人,说明他的出度+1,差值就会-1
}
auto it = find(count.begin()+1, count.end(), N-1);
return it == count.end() ? -1 : it - count.begin();
}
};