use std::collections::{HashMap, HashSet};
/**
997. Find the Town Judge
https://leetcode.com/problems/find-the-town-judge/
In a town, there are n people labeled from 1 to n. There is a rumor that one of these people is secretly the town judge.
If the town judge exists, then:
1. The town judge trusts nobody.
2. Everybody (except for the town judge) trusts the town judge.
3. There is exactly one person that satisfies properties 1 and 2.
You are given an array trust where trust[i] = [ai, bi] representing that the person labeled ai trusts the person labeled bi.
Return the label of the town judge if the town judge exists and can be identified, or return -1 otherwise.
Example 1:
Input: n = 2, trust = [[1,2]]
Output: 2
Example 2:
Input: n = 3, trust = [[1,3],[2,3]]
Output: 3
Example 3:
Input: n = 3, trust = [[1,3],[2,3],[3,1]]
Output: -1
Constraints:
1. 1 <= n <= 1000
2. 0 <= trust.length <= 10^4
3. trust[i].length == 2
4. All the pairs of trust are unique.
5. ai != bi
6. 1 <= ai, bi <= n
*/
pub struct Solution {}
impl Solution {
/*
Solution: HashMap+HashSet, Time:O(n), Space:O(n)
*/
pub fn find_judge(n: i32, trust: Vec<Vec<i32>>) -> i32 {
let count = trust.len();
if (count == 0) {
//check some corner case
return if n == 1 { 1 } else { -1 };
}
let mut peoplesWillTrustAnother: HashSet<i32> = HashSet::new();
let mut mappingForJudge: HashMap<i32, Vec<i32>> = HashMap::new();
for i in 0..count {
//[0] is can be trust other, there are should not be a Judge
peoplesWillTrustAnother.insert(trust[i][0]);
//key is someone and value is list of everyone who trusts that people
let vec = mappingForJudge.entry(trust[i][1] as i32).or_insert(Vec::new());
vec.push(trust[i][0]);
}
/*
Checking for Judge:
1. not in peoplesWillTrustAnother;
2. has N-1 peoples trusts
*/
for i in 1..n + 1 {
if (peoplesWillTrustAnother.contains(&i)) {
continue;
}
//if mappingForJudge.get(&i) can decomposed to array
if let Some(array) = mappingForJudge.get(&i) {
if (array.len() == (n - 1) as usize) {
return i;
}
}
}
-1
}
}