题目概述:
小镇里有 n 个人,按从 1 到 n 的顺序编号。传言称,这些人中有一个暗地里是小镇法官。
如果小镇法官真的存在,那么:
小镇法官不会信任任何人。
每个人(除了小镇法官)都信任这位小镇法官。
只有一个人同时满足属性 1 和属性 2 。
给你一个数组 trust ,其中 trust[i] = [ai, bi] 表示编号为 ai 的人信任编号为 bi 的人。
如果小镇法官存在并且可以确定他的身份,请返回该法官的编号;否则,返回 -1 。
示例:
输入:n = 2, trust = [[1,2]]
输出:2
思路1:使用二维数组
定义一个二维数组,行表示当前这个人相信其他人,列表示其他人相信当前这个人。题目中要求:
(1)法官不相信任何人,那么也就是说法官所在的二维数组这一行都为0
(2)所有人都相信法官,言下之意就是法官所在的二维数组这一列除了res[i][i]=0之外,其余都为1
算法实现:
class Solution {
public int findJudge(int n, int[][] trust) {
//定义一个二维数组用来存储谁信任谁
int[][] res = new int[n][n];
//将起始点所在的行都设置为1
for(int i=0;i<trust.length;i++){
res[trust[i][0]-1][trust[i][1]-1] = 1;
}
// List<Integer> list = new ArrayList<>();
int num = 0;
//找到剩余不为起始点的元素
for(int i=0;i<res.length;i++){
boolean find = true;
for(int j=0;j<res.length;j++){
if(res[i][j]==1){
find = false;
}
}
if(find==true){
num = i+1;
}
}
if(num==0){
return -1;
}
for(int i=0;i<res.length;i++){
if(i!=num-1&&res[i][num-1]==0){
return -1;
}
}
return num;
}
}
思路2:使用图论知识
可以利用图论当中的知识进行求解:
(1)法官不相信任何人,表示法官这个元素的出度为0;
(2)所有人都相信法官,表示法官的入读为元素个数-1;
我们只需要定义一个数组用来存储出度和入读,来找这个满足条件的点即可。
代码实现:
class Solution {
public int findJudge(int n, int[][] trust) {
//定义数组用来存储出度
int[] out = new int[n];
//存储入读
int[] in = new int[n];
//出度
for(int i=0;i<trust.length;i++){
out[trust[i][0]-1]+=1;
}
//入度
for(int i=0;i<trust.length;i++){
in[trust[i][1]-1]+=1;
}
int num = 0;
for(int i=0;i<out.length;i++){
if(out[i]==0){
num = i+1;
}
}
if(num==0){
return -1;
}
//判断num的入度
if(in[num-1]==n-1){
return num;
}else{
return -1;
}
}
}