
为社交PC客户端的N级好友查询需求,设计基于**多级邻接表(层次化图结构)**的解决方案,时间复杂度O(Nk),空间复杂度O(NV+E),通过动态更新、LRU缓存和预计算优化,适用于中小规模;大规模场景可结合图数据库,并权衡分布式与索引成本。
用户关系本质是图结构,好友关系为边。邻接表是图的经典表示,每个节点存储邻居列表。为支持N级查询,构建多级邻接表(按层级存储邻居),通过**广度优先搜索(BFS)**逐层遍历。类比:社交网络如一棵网状树,邻接表是每个用户的“好友通讯录”,多级就是多层的通讯录,查询N级好友就像逐层展开通讯录。BFS保证按层级顺序遍历,避免深度优先搜索(DFS)的深度优先导致结果顺序混乱或遗漏。
| 数据结构 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 多级邻接表(内存图) | 每个节点存储多级邻居列表(1级、2级...N级) | 空间效率高(O(N*V+E)),查询需遍历邻居 | 小规模图(客户端内存足够),实时查询 | 需预加载所有数据,不适合大规模,N级查询需多次遍历 |
| 图数据库(如Neo4j) | 基于图模型,支持节点-关系索引和Cypher查询 | 分布式存储,支持复杂查询,持久化 | 大规模社交网络,跨设备同步,持久化 | 查询性能受索引数量、分布式存储影响,部署成本高 |
假设用户ID为1,查询2级好友。邻接表结构:
多级邻接表遍历伪代码:
# 1级邻接表
adj = {1: [2,3], 2: [1,4], 3: [1,5]}
# 2级邻接表(1级邻居的邻居)
adj_2 = {1: [4,5], 2: [], 3: []}
def bfs_n_level(user, n):
visited = set()
queue = [(user, 0)]
result = []
while queue:
cur, level = queue.pop(0)
if level == n:
result.append(cur)
elif level < n:
neighbors = adj.get(cur, [])
for neighbor in neighbors:
if neighbor not in visited:
visited.add(neighbor)
queue.append((neighbor, level+1))
return result
# 查询用户1的2级好友
print(bfs_n_level(1, 2)) # 输出 [4, 5]
面试官您好,针对社交PC客户端的N级好友查询需求,我会设计一种基于多级邻接表(层次化图结构)的解决方案。核心思路是:用邻接表存储用户节点及其直接好友(1级关系),并通过广度优先搜索(BFS)逐层遍历邻居,第N层即为N级好友。时间复杂度分析:BFS遍历N层时,每层节点数乘以平均邻居数k,总复杂度O(Nk),比如k=10时N=5则复杂度约50k次操作。空间复杂度:多级邻接表存储N层关系,空间为O(NV+E),额外空间来自多级存储(如N=3时存储3层邻居列表)。动态更新方面,通过事件监听机制(发布-订阅模式)实时同步好友增删,确保数据实时性。缓存策略采用LRU缓存热门用户的关系数据,预计算常用N级关系(如离线计算用户1的2-3级好友存入缓存),减少实时遍历。对于大规模场景,引入图数据库(如Neo4j),利用节点-关系索引加速查询,但需注意索引数量过多可能影响性能。总结:中小规模用内存多级邻接表+BFS,时间O(Nk),空间O(NV+E);大规模用图数据库,结合缓存优化。