一、题目描述
In a town, there are N people labelled from 1 to N. There is a rumor that one of these people is secretly the town judge.
If the town judge exists, then:
The town judge trusts nobody.
Everybody (except for the town judge) trusts the town judge.
There is exactly one person that satisfies properties 1 and 2.
You are given trust, an array of pairs trust[i] = [a, b] representing that the person labelled a trusts the person labelled b.
If the town judge exists and can be identified, return the label of the town judge. Otherwise, return -1.
Input: N = 3, trust = [[1,3],[2,3]]
Output: 3
Input: N = 3, trust = [[1,3],[2,3],[3,1]]
Output: -1
二、题解
题意:[a, b]
表示 a
相信 b
,所有点构成了一个有向图,找到被所有人相信但自己不相信任何人的那个人。
方法一:dfs 判环?
错误思想:如果图存在环,则不存在法官。否则,返回入度为 N-1
的人。
A1:因为并没有标明除了法官的其它人不能互相信任,即图中存在环,也是可以有法官的。比如:
4
[[1,2],[1,3],[2,1],[2,3],[1,4],[4,3],[4,1]]
预期:3
输出:-1
boolean[] ving, ved;
Map<Integer, List<Integer>> graph;
public int findJudge(int N, int[][] edges) {
graph = new HashMap<>();
for (int i = 1; i <= N; i++) {
graph.put(i, new LinkedList<>());
}
for (int[] edge : edges) {
graph.get(edge[1]).add(edge[0]);
}
ving = new boolean[N+1];
ved = new boolean[N+1];
for (int i = 1; i <= N; i++) {
if (dfs(i))
return -1;
}
int[] in = new int[1000+50];
for (int[] t : edges) {
in[t[1]]++;
}
for (int i = 1; i <= N; i++) {
if (in[i] == N-1)
return i;
}
return -1;
}
private boolean dfs(int i) {
//证明有环
if (ving[i]) return true;
if (ved[i]) return false;
ving[i] = true;
for (int toTake : graph.get(i)) {
if (dfs(toTake))
return true;
}
ving[i] = false;
ved[i] = true;
return false;
}
方法二:统计出入度
因为法官的入度为 N-1,出度一定是 0,所以只需要统计一遍即可。
public int findJudge(int N, int[][] edges) {
int[] in = new int[N+1];
int[] out = new int[N+1];
for (int[] edge : edges) {
in[edge[1]]++;
out[edge[0]]++;
}
for (int i = 1; i <= N; i++) {
if (in[i] == N-1 && out[i] == 0)
return i;
}
return -1;
}
复杂度分析
- 时间复杂度: ,
- 空间复杂度: ,
方法三:邻接矩阵记录信息
- 在 N × N 的矩阵中,用 1 表示信任,0 表示不存在信任。
- 如果有某个人是法官,那么一定存在 1 列全是
1
,一行中除了自己全是0
。
public int findJudge(int N, int[][] edges) {
int[][] matrix = new int[N+1][N+1];
for (int[] edge : edges) {
matrix[edge[0]][edge[1]] = 1;
}
for (int i = 1; i <= N; i++) {
matrix[i][i] = 1;
}
for (int c = 1; c <= N; c++) {
boolean isAllOne = true;
for (int r = 1; r <= N; r++) {
if (matrix[r][c] == 0) {
isAllOne = false;
break;
}
}
if (isAllOne == false)
continue;
boolean found = true;
for (int k = 1; k <= N; k++) {
if (matrix[c][k] == 1 && c != k) {
found = false;
break;
}
}
if (found)
return c;;
}
return -1;
}
复杂度分析
- 时间复杂度: ,
- 空间复杂度: ,