LintCode 1903. 滴滴面试:部门统计
九章题解www.jiuzhang.com题目描述
公司给你提供了所有员工的信息,包括其ID,姓名和所属部门。
以及他们之间的朋友关系,每个关系中由2个ID组成,如 "1, 2" 代表1
号员工和2
号员工是朋友。
朋友关系不具有传递性,即B
、C
都是A
的朋友,但B
和C
不一定是朋友。
请计算每个部门中与其它部门的员工有朋友关系的员工个数。
说明
样例中,Engineer
的1
号员工和HR
的2
号员工是朋友关系,3
号员工和Business
的4
号员工是朋友关系,所以Engineer
有2
个人和其它部门有朋友关系,输出"Engineer: 2 of 3“。
样例
样例输入:
employees = [
"1, Bill, Engineer",
"2, Joe, HR",
"3, Sally, Engineer",
"4, Richard, Business",
"6, Tom, Engineer"
]
friendships = [
"1, 2",
"1, 3",
"3, 4"
]
样例输出:
"Engineer: 2 of 3"
"HR: 1 of 1"
"Business: 1 of 1"
题解
解题思路
这是一道模拟题,考察的是对各种STL
容器的灵活运用,有助于代码的实现。
对于员工的编号和不同的部门,我们可以赋予它们一个临时的编号,通过映射map
这个数据结构。根据这个编号来找到具体的对象的信息,以及统计好员工的部门归属。对于每个部门中有符合题目要求条件的人,因为人员可能会重复,所以每一个部门用一个集合set
来维护。处理好这些信息后进行最后的统计和输出即可。
代码思路
- 用
(employeeIdx, employeeCount)
和(departmentIdx, departmentCount)
维护员工和部门的临时编号信息。 - 用
belong
来维护员工的归属。 - 通过字符串处理可以得到每条消息的第一个和最后一个信息。
- 按照题目要求,如果有两名员工在不同部门,记录这些信息。
- 统计最终的结果。
复杂度分析
设员工信息条数为N
,朋友关系条数为M
,部门数为K
时间复杂度
- 每个映射
map
和集合set
单次插入和查询的复杂度是O(logN)
,如果是HashMap
,HashSet
的话是O(1)
。 - 总的复杂度为
O(NlogN + MlogM + KlogK)
或O(N + M + K)
。
空间复杂度
- 消耗的空间为
O(N + M + K)
。
Java:
/**
* This reference program is provided by @jiuzhang.com
* Copyright is reserved. Please indicate the source for forwarding
*/
public class Solution {
/**
* @param employees: information of the employees
* @param friendships: the friendships of employees
* @return: return the statistics
*/
public List<String> departmentStatistics(List<String> employees, List<String> friendships) {
// 部门人数和员工人数,及编号
int departmentCount = 0, employeeCount = 0;
Map<String, Integer> departmentIdx = new HashMap<String, Integer>();
Map<String, Integer> employeeIdx = new HashMap<String, Integer>();
// 每个部门名称
List<String> departmentNames = new ArrayList<String>();
// 每个部门人数
List<Integer> departmentNumbers = new ArrayList<Integer>();
// 员工归属,员工ID -> 部门ID
Map<Integer, Integer> belong = new HashMap<Integer, Integer>();
// 每个部门有符合条件的员工ID的集合
Set<Integer>[] haveDiffFriend;
for (String employee: employees) {
List<String> info = getInfo(employee);
if (! departmentIdx.containsKey(info.get(1))) {
departmentIdx.put(info.get(1), departmentCount++);
departmentNumbers.add(0);
departmentNames.add(info.get(1));
}
if (! employeeIdx.containsKey(info.get(0))) {
employeeIdx.put(info.get(0), employeeCount++);
}
Integer idx = departmentIdx.get(info.get(1));
departmentNumbers.set(idx, departmentNumbers.get(idx) + 1);
belong.put(employeeIdx.get(info.get(0)), departmentIdx.get(info.get(1)));
}
haveDiffFriend = new HashSet[departmentCount];
for (int i = 0; i < departmentCount; i++) {
haveDiffFriend[i] = new HashSet<Integer>();
}
for (String friendship: friendships) {
List<String> info = getInfo(friendship);
int employeeA = employeeIdx.get(info.get(0));
int employeeB = employeeIdx.get(info.get(1));
int departmentA = belong.get(employeeA);
int departmentB = belong.get(employeeB);
if (departmentA != departmentB) {
haveDiffFriend[departmentA].add(employeeA);
haveDiffFriend[departmentB].add(employeeB);
}
}
List<String> result = new ArrayList<String>();
for (String departmentName: departmentNames) {
int idx = departmentIdx.get(departmentName);
result.add(departmentName + ": "
+ haveDiffFriend[idx].size()
+ " of "
+ departmentNumbers.get(idx));
}
return result;
}
private List<String> getInfo(String message) {
int firstComma = message.indexOf(',');
int lastComma = message.lastIndexOf(',');
String firstInfo = message.substring(0, firstComma);
String lastInfo = message.substring(lastComma + 2);
List<String> info = new ArrayList<>();
info.add(firstInfo);
info.add(lastInfo);
return info;
}
}
Python:
his reference program is provided by @jiuzhang.com
# Copyright is reserved. Please indicate the source for forwarding
class Solution:
"""
@param employees: infomation of the employees
@param friendships: the friendships of employees
@return: return the statistics
"""
def departmentStatistics(self, employees, friendships):
# 部门人数和员工人数,及编号
department_count, employee_count = 0, 0
department_idx, employee_idx = {}, {}
# 每个部门名称
department_names = []
# 每个部门人数
department_numbers = []
# 员工归属,员工ID -> 部门ID
belong = {}
# 每个部门有符合条件的员工ID的集合
have_diff_friend = []
for employee_info in employees:
employee, department = self.getInfo(employee_info)
if department not in department_idx:
department_idx[department] = department_count
department_count += 1
have_diff_friend.append(set())
department_numbers.append(0)
department_names.append(department)
if employee not in employee_idx:
employee_idx[employee] = employee_count
employee_count += 1
department_numbers[department_idx[department]] += 1
belong[employee_idx[employee]] = department_idx[department]
for friendship in friendships:
info = self.getInfo(friendship)
employee_a = employee_idx[info[0]]
employee_b = employee_idx[info[1]]
department_a = belong[employee_a]
department_b = belong[employee_b]
if department_a != department_b:
have_diff_friend[department_a].add(employee_a)
have_diff_friend[department_b].add(employee_b)
result = []
for departmentName in department_names:
idx = department_idx[departmentName]
result.append(departmentName + ': '
+ str(len(have_diff_friend[idx]))
+ ' of '
+ str(department_numbers[idx]))
return result
def getInfo(self, message):
info = message.split(', ')
return [info[0], info[len(info) - 1]]
C++:
/**
* This reference program is provided by @jiuzhang.com
* Copyright is reserved. Please indicate the source for forwarding
*/
class Solution {
public:
/**
* @param employees: infomation of the employees
* @param friendships: the friendships of employees
* @return: return the statistics
*/
vector<string> departmentStatistics(vector<string> &employees, vector<string> &friendships) {
// 部门人数和员工人数,及编号
int departmentCount = 0, employeeCount = 0;
map<string, int> departmentIdx, employeeIdx;
// 每个部门名称
vector<string> departmentNames;
// 每个部门人数
vector<int> departmentNumbers;
// 员工归属,员工ID -> 部门ID
map<int, int> belong;
// 每个部门有符合条件的员工ID的集合
vector<set<int>> haveDiffFriend;
for (const string& employee: employees) {
pair<string, string> info = getInfo(employee);
if (not departmentIdx.count(info.second)) {
departmentIdx[info.second] = departmentCount++;
haveDiffFriend.push_back(set<int>());
departmentNumbers.push_back(0);
departmentNames.push_back(info.second);
}
if (not employeeIdx.count(info.first)) {
employeeIdx[info.first] = employeeCount++;
}
departmentNumbers[departmentIdx[info.second]]++;
belong[employeeIdx[info.first]] = departmentIdx[info.second];
}
for (const string& friendship: friendships) {
pair<string, string> info = getInfo(friendship);
int employeeA = employeeIdx[info.first];
int employeeB = employeeIdx[info.second];
int departmentA = belong[employeeA];
int departmentB = belong[employeeB];
if (departmentA != departmentB) {
haveDiffFriend[departmentA].insert(employeeA);
haveDiffFriend[departmentB].insert(employeeB);
}
}
vector<string> result;
for (string& departmentName: departmentNames) {
int idx = departmentIdx[departmentName];
result.push_back(departmentName + ": "
+ to_string(haveDiffFriend[idx].size())
+ " of "
+ to_string(departmentNumbers[idx]));
}
return result;
}
// 获取字符串的信息,本题比较特殊,每句话的第一个和最后一个信息有用
pair<string, string> getInfo(string message) {
int firstComma = message.find(',');
int lastComma = message.find_last_of(',');
string firstInfo = message.substr(0, firstComma);
string lastInfo = message.substr(lastComma + 2);
return make_pair(firstInfo, lastInfo);
}
};
更多大厂高频考题,请点击LintCode进行在线评测