从零开始找出“聚会隐藏王”!Swift 解密 LeetCode 名人问题

文章目录

摘要描述举个例子:

题解答案(Swift)题解代码分析第一步:候选人筛选第二步:验证候选人

示例测试及结果时间复杂度空间复杂度实际场景中的应用QA 环节Q1:如果有多个名人怎么办?Q2:如何避免多次调用 `knows()` 函数?

总结未来展望

摘要

在一群人中找到“名人”听起来像是八卦聚会的开场话题,但在 LeetCode 上,它其实是一个非常经典的逻辑推理问题,涉及图论中的入度和出度分析。这篇文章将带你一步步理解这道题的本质、实现它的高效解法,并用 Swift 写出一套可运行的代码。最后我们还会分析它的性能,并探讨这类问题在实际生活或系统设计中可能的应用。

描述

题目要求你在一个 n 个人的聚会中找出所谓的“名人”。每个人被编号为 0 到 n-1。你可以调用一个函数 knows(a, b) 来判断 a 是否认识 b。

题设的定义是:

名人不会认识任何人(除了自己)。所有人都认识名人。

你的任务是找出这位名人,或者如果没有名人,则返回 -1。

举个例子:

输入: n = 3,knows关系如下:

Person 0 knows 1 and 2

Person 1 knows 2

Person 2 knows no one

输出: 2

解释: 2 是名人,其他人都认识他,他不认识任何人

题解答案(Swift)

class Solution {

private var knowsMatrix: [[Bool]] = []

init(knowsMatrix: [[Bool]]) {

self.knowsMatrix = knowsMatrix

}

private func knows(_ a: Int, _ b: Int) -> Bool {

return knowsMatrix[a][b]

}

func findCelebrity(_ n: Int) -> Int {

var candidate = 0

// 第一次遍历找候选人

for i in 1..

if knows(candidate, i) {

candidate = i

}

}

// 第二次确认候选人是否是名人

for i in 0..

if i != candidate {

if knows(candidate, i) || !knows(i, candidate) {

return -1

}

}

}

return candidate

}

}

题解代码分析

第一步:候选人筛选

我们一开始假设 0 是名人,然后从 1 到 n-1 遍历:

如果 candidate 认识 i,说明 candidate 不可能是名人,把 candidate 设为 i。如果 candidate 不认识 i,则保留当前的候选人。

为什么这么做有效?因为如果某人认识另一个人,那他肯定不是名人;而如果他不认识另一个人,那另一个人也不能是名人(因为名人应该被所有人认识)。

第二步:验证候选人

我们已经筛选出一个可能的候选人,还需要再次遍历确认:

他不应该认识任何人。所有人都应该认识他。

只要有一个不满足,这个人就不是名人,直接返回 -1。

示例测试及结果

let matrix = [

[false, true, true],

[false, false, true],

[false, false, false]

]

let solution = Solution(knowsMatrix: matrix)

print(solution.findCelebrity(3)) // 输出 2

在这个示例中:

0 认识 1 和 2。1 认识 2。2 谁都不认识。

很明显,2 被所有人认识,且自己不认识任何人,所以他就是名人。

时间复杂度

候选人筛选:O(n)验证候选人:O(n)

总的时间复杂度为 O(n),远优于暴力的 O(n²) 方案。

空间复杂度

我们没有使用额外空间(除了常量变量),所以空间复杂度是 O(1)。

实际场景中的应用

这道题虽然出现在算法平台上,但类似的逻辑常常出现在实际系统中,比如:

在社交网络中判断某个账号是否是“信息中心”。在组织结构图中找出某位只被汇报、却不汇报任何人的高管。在事件链中寻找最终的“接收者”或根节点。

QA 环节

Q1:如果有多个名人怎么办?

答: 根据题目要求,最多只有一个名人,所以我们不考虑多个名人的情况。但在实际系统中,可能需要返回一个列表,可以在验证阶段收集所有满足条件的节点。

Q2:如何避免多次调用 knows() 函数?

答: 可以做记忆化缓存(比如用字典存 knows(i, j) 的结果),在大规模系统中这是非常重要的优化。

总结

“名人问题”本质上是图论中的一个“入度为 n-1,出度为 0”的节点查找问题。这题不仅考验你对关系判断的抽象能力,也考验你在有限信息下进行逻辑推理的能力。Swift 在处理数组和逻辑结构时有很好的表达力,是非常适合实现这类算法的语言。

未来展望

名人问题只是“信息流向分析”的冰山一角。如果你在做知识图谱、社交图、组织图、推荐系统,其实都能用上类似的入度-出度分析方法。后续我们还可以扩展到带权图、多层图等高级话题。

柳承敏辞去韩国乒协会长一职,并将挑战韩国体育“一把手”的位置
徐洁—TIBHAR签约队员
Copyright © 2022 02年世界杯冠军|世界杯 巴西|168快赢世界杯速报站|168kuaiyin.com All Rights Reserved.