题目
-
题目描述
你正在为一个社交网络平台开发好友推荐功能。
平台上有N个用户(每个用户使用1到N的整数编号),同时系统中维护了用户之间的好友关系。
为了推荐新朋友,平台决定采用 “共同好友数量" 作为衡量两个用户之间相似度的标准。
系统根据输入用户编号K,输出与此用户K相似度最高的前L个用户ID来推荐给用户K。
相似度定义:两个用户非好友,两个用户的相似度为拥有的共同好友数(例如用户A和用户B,只有共同好友C和D,相似度=2)。 -
解答要求
时间限制:C/C++1000ms,其他语言:2000ms。
内存限制: C/C++256MB,其他语言:512MB。 -
输入
第一行包含四个整数 N、M、K 和 L,分别表示用户的数量(N),好友记录条数(M)、查询的用户编号(K)和推荐的好友数量(L)。
接下来 M 行,每行包含两个整数编号 X 和 Y,表示编号为 X 和 Y 用户是好友。
1.输入格式都是标准的,无需考虑输出异常场景(不会包含用户和自己是好友的输入,例如1 1)
2.用户数不超过1024,用户编码最大1024
3.好友记录数不超过10240 -
输出
根据输入K和L,输出和用户K相似度最高的L个用户编码。
1.输出相似度最高的前L个用户编码,按照相似度从高到低排序
2.如果有相似度相同的可能好友,按照用户编号从小到大排序
3.如果推荐的好友个效不足L个,则推荐与用户K无无共同好友关系的用户(陌生人)作为可能好友,如果推荐仍不满足L个用户,剩余推荐用户编码使用0来占位 -
样例1
输入:
6 7 3 2
1 2
1 3
2 3
3 4
3 5
4 5
5 6
输出:
6 0
解释:
输入包含了6个用户,7条好友记录,给用户ID编号为3的用户推荐2个好友。
输出只有编号为6的用户可能是编号3用户的可能好友;
尝试推荐与编号3用户无共同好友的其他用户,由于除编号为6的用户之外,其他用户和编号3用户都是好友,所以找不到陌生人作为推荐的第二个用户;
推荐结果不足2个用户,所以推荐的第二个用户编码使用0来占位补足。 -
样例2
输入
8 11 1 3
1 2
1 3
2 3
3 4
3 5
4 5
5 6
6 7
7 8
1 8
2 7
输出:
7 4 5
解释:
输入包含了8个用户,11条好友记录,给用户ID号为1的用户推荐3个好友。按照相似度排序推荐给用户1的相关好友:7 4 5。
解题思路
- 存储每个用户的好友集合
main 主函数内 unordered_map<int, unordered_set<int>> 创建 1个无序映射 friends,该映射中的每个元素都是 1 个无序集合,表示 每个用户的好友集合 。依据输入数据,为每个人的朋友集合里添加好友。若最后有人没有好友,则令这个人的好友集合为空,确保每个人都有集合(为了便于后续遍历计算)。 - 计算其他用户和用户K的相同好友数量
unordered_map<int, int> 创建1个无序映射 similarity,该映射的每个元素代表其他用户与用户K相同的好友数量。
const unordered_set<int> & friendsOfK = friends.at(K); 提取出用户K的好友集合。
对 friends 进行遍历,提取出当前遍历的 用户 ID 及 其好友集合,若当前遍历到的用户就是用户 K 或者 已经是用户K的好友则跳过该用户遍历下一个用户;否则计算当前遍历到用户与用户K的相同好有数量,最后进入下一次遍历。 - 依据相同好友数量以及用户ID对用户进行排序
如果相同朋友数相同,则按照用户ID排序;否则按照相同朋友数排序。 - 依据排序结果提取前L个用户
若推荐结果不足,则尾补零。
代码
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <algorithm>
using namespace std