大家好,欢迎来到无限大的频道。
今日继续给大家带来力扣题解。
题目描述(简单):
找到小镇的法官
小镇里有 n 个人,按从 1 到 n 的顺序编号。传言称,这些人中有一个暗地里是小镇法官。
如果小镇法官真的存在,那么:
-
小镇法官不会信任任何人。
-
每个人(除了小镇法官)都信任这位小镇法官。
-
只有一个人同时满足属性 1 和属性 2 。
给你一个数组 trust ,其中 trust[i] = [ai, bi] 表示编号为 ai 的人信任编号为 bi 的人。
如果小镇法官存在并且可以确定他的身份,请返回该法官的编号;否则,返回 -1 。
解题思路:
这个我们需要读懂题目,需要找到一个符合特定性质的人作为小镇法官。如果有这样的人,那么:
-
这个人不会信任任何人。
-
所有其他人都信任这个人。
我们可以使用一个简单的计数来追踪这些关系:
-
构造一个数组 trustCount,其长度为 n + 1(为了方便地处理1到n的编号)。
-
减少 a 的信任计数,trustCount[a]--(表示 a 去信任别人,因而a不可能是法官)。
-
增加 b 的信任计数,trustCount[b]++(表示有一个人信任 b,增加 b 被信任的可能性)。
-
对于每一个 trust[i] = [a, b]:
-
-
最后,遍历 trustCount 数组,找到是否存在一个人编号 i,使得 trustCount[i] == n - 1。这意味着此人不信任任何人,但其他所有人都信任此人。
-
如果找到了这样的 i,那么 i 就是小镇法官,否则返回 -1。
参考代码如下:
int findJudge(int n, int** trust, int trustSize, int* trustColSize) {
if (n == 1) return 1; // Corner case for a single person town
int trustCount[n + 1];
for (int i = 0; i <= n; i++) {
trustCount[i] = 0;
}
for (int i = 0; i < trustSize; i++) {
int a = trust[i][0];
int b = trust[i][1];
trustCount[a]--; // a trusts someone
trustCount[b]++; // someone trusts b
}
for (int i = 1; i <= n; i++) {
if (trustCount[i] == n - 1) {
return i;
}
}
return -1;
}
详细解题思路解析:
-
初始化数组:为简化处理,把所有人的信任度计数存储在 trustCount 中。
-
遍历信任关系:我们遍历这个 trust 数组,每当 a 信任 b,就对 a 的信任度减1,对 b 的信任度加1。
-
检查条件:在所有人中,如果有一位人士的信任度为 n-1,那么这就是我们要找的小镇法官,否则法官不存在。
-
边界特例:如果小镇有且仅有一人 (n=1),那么这个人自然是法官,因为他不需要去信任其他人。
时间复杂度:
-
初始化 trustCount 数组:
-
我们创建一个大小为 n + 1 的数组,并将其初始化为 0。这一过程的时间复杂度为 (O(n))。
-
-
遍历 trust 数组:
-
我们遍历 trust 数组的每一对信任关系。在每次遍历中,我们对 trustCount 数组进行两次操作(分别增加和减少计数)。如果 trust 数组的大小为 m,那么这一过程的时间复杂度为 (O(m))。
-
-
检查 trustCount 数组:
-
最后,我们遍历 trustCount 数组(从 1 到 n),寻找信任度为 n - 1 的人。这一过程的时间复杂度为 (O(n))。
-
综合以上三步,整体的时间复杂度为: [ O(n + m) ] 其中 (n) 是小镇中人的数量,(m) 是信任关系的数量。
空间复杂度:
-
trustCount 数组:
-
我们使用了一个大小为 (n + 1) 的数组来存储每个人的信任度。这占用的空间为 (O(n))。
-
-
输入的 trust 数组:
-
输入的 trust 数组本身也占用空间,但这属于输入的一部分,不算作额外的空间复杂度。
-
因此,整体的空间复杂度为: [ O(n) ]
总结:
-
时间复杂度:(O(n + m))
-
空间复杂度:(O(n))