LeetCode_997_找到小镇的法官

小镇里有 n 个人,按从 1 到 n 的顺序编号。传言称,这些人中有一个暗地里是小镇法官。

如果小镇法官真的存在,那么:

  • 小镇法官不会信任任何人。
  • 每个人(除了小镇法官)都信任这位小镇法官。
  • 只有一个人同时满足属性 1 和属性 2 。

给你一个数组 trust ,其中 trust[i] = [ai, bi] 表示编号为 ai 的人信任编号为 bi 的人。

如果小镇法官存在并且可以确定他的身份,请返回该法官的编号;否则,返回 -1 。

示例 1:
输入:n = 2, trust = [[1,2]]
输出:2


示例 2:
输入:n = 3, trust = [[1,3],[2,3]]
输出:3


示例 3:
输入:n = 3, trust = [[1,3],[2,3],[3,1]]
输出:-1

找到小镇的法官


额, 读懂题目都花了一段时间, 其中有个条件题目没有明确说出来, 一个人可以信任多个人, 同时多个人也可以信任一个人,  既有1对多, 又有多对1, 是不是有点有向图的感觉了.

 用一个数组beTruseArray存放被人信任的数量, 下表为人, 值为被信任的数量.比如beTruseArray[3] = 5, 表示下表为3的人, 被5个人信任;   beTruseArray[4] = 1, 表示,下表为4的人 被1个人信任. 有了这个数组找到一个index, 使得  beTruseArray[index] == n-1 , 那这个index就可能是法官了, 我们先叫他 疑似法官

题目还有一个要求, 法官不会信任何人, 验证这个条件, 有2种方式

  • 可以通过在遍历一次trust来处理,
    • 如果疑似法官的人有任何信任的人, 就可以返回-1, 
    • 如果遍历完, 疑似法官无任何信任的人, 那说明他就是法官了, 返回index
  • 上面的方案还需要一次遍历, 可以通过在第一次遍历生成beTruseArray的时候, 在同时生成一个数组personTrustArray,   数组的下表为人, 值为这个人信任的所有人构成的数组,  比如personTrustArray[3] = [1,2], 表示下表为3的人, 信任1,2;   personTrustArray[1] = [2], 表示下表为1的人信任2.
    当需要验证疑似法官时, 直接取出personTrustArray[index],
    • 如果这个数组不为空, 那说明满足index还信任其他人, 不满足条件, 返回 -1
    • 如果这个数组为空, 那说明满足法官条件, 返回index
class Solution {
    func findJudge(_ n: Int, _ trust: [[Int]]) -> Int {
        if n == 1 {
            return 1
        }
        // 下表为人, 值为被信任的数量
        var beTruseArray = Array.init(repeating: 0, count: n+1)
        // 下表为人, 值为这个人信任的所有人构成的数组
        var personTrustArray = Array.init(repeating: [Int](), count: n+1)
        for onePersonArray in trust {
            let person = onePersonArray.first!
            let trustPerson = onePersonArray.last!
            beTruseArray[trustPerson] += 1
            personTrustArray[person].append(trustPerson)
        }
        // 找到信任数为n-1的人,这个人可能是法官
        if let index = beTruseArray.firstIndex(of: n-1) {
            // 在看信任数为n-1的人,有没有信任其他人,
            // 无信任其他人, 符合法官条件
            // 有信任其他人, 不符合法官条件
            if personTrustArray[index].isEmpty {
                return index
            } else {
                return -1
            }
        }
        return -1
    }
}

 时间复杂度是O(N),  只需要遍历一次就可以完成所有判断. 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值