✅创作者:陈书予
🎉个人主页:陈书予的个人主页
🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区
🌟专栏地址: Java华为OD机试真题(2022&2023)
文章目录
- 1. 题目描述
- 2. 输入描述
- 3. 输出描述
- 4. Java算法源码
- 5. 测试
- 6.解题思路
1. 题目描述
公司某部门软件教导团正在组织新员工每日打卡学习活动,他们开展这项学习活动已经一个月了,所以想统计下这个月优秀的打卡员工。每个员工会对应一个id,每天的打卡记录记录当天打卡员工的id集合,一共30天。
请你实现代码帮助统计出打卡次数top5的员工。假如打卡次数相同,将较早参与打卡的员工排在前面,如果开始参与打卡的时间还是一样,将id较小的员工排在前面。
注:不考虑并列的情况,按规则返回前5名员工的id即可,如果当月打卡的员工少于5个,按规则排序返回所有有打卡记录的员工id。
2. 输入描述
第一行输入为新员工数量N,表示新员工编号id为0到N-1,N的范围为[1,100];
第二行输入为30个整数,表示每天打卡的员工数量,每天至少有1名员工打卡;
之后30行为每天打卡的员工id集合,id不会重复;
3. 输出描述
按顺序输出打卡top5员工的id,用空格隔开。
补充:同一天打卡的员工没有时间上早晚的区别。不保证所有员工都会打卡。排名只针对有打卡记录的员工。
4. Java算法源码
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 新员工数量N
int N = Integer.valueOf(sc.nextLine());
// 每天打卡的员工数量
int[] clockArr = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
Map<Integer, int[]> map = new HashMap<>();
// 之后30行为每天打卡的员工id集合,id不会重复;
for (int i = 0; i < 30; i++) {
for (int j = 0; j < clockArr[i]; j++) {
int input = sc.nextInt();
if (input > N - 1) {
continue;
}
int[] temp = new int[2];
if (map.containsKey(input)) {
temp = map.get(input);
++temp[1];
} else {
temp[0] = i;
temp[1] = 1;
}
map.put(input, temp);
}
}
List<Map.Entry<Integer, int[]>> mapList = new ArrayList<>(map.entrySet());
mapList.sort((a, b) -> {
// 按打卡次数排序
if (b.getValue()[1] < a.getValue()[1]) {
return -1;
} else if (b.getValue()[1] == a.getValue()[1]) {
// 天数相同的第一次打卡时间靠前
if (b.getValue()[0] > a.getValue()[0]) {
return -1;
}
}
return 1;
});
StringBuilder builder = new StringBuilder();
// //小于5的取所有,大于5的只取5
for (int i = 0; i < (Math.min(mapList.size(), 5)); i++) {
builder.append(mapList.get(i).getKey()).append(" ");
}
System.out.println(builder.substring(0, builder.length() - 1));
}
5. 测试
6.解题思路
为了解决这个问题,我们可以按照以下步骤进行操作:
- 读取新员工数量N。
- 读取30个整数,表示每天的打卡员工数量。
- 创建一个HashMap,用于存储员工的打卡信息。键为员工ID,值为一个长度为2的整数数组,数组的第一个元素表示员工第一次打卡的日期,第二个元素表示员工的打卡次数。
- 遍历每天的打卡信息:
- 对于每天的打卡信息,读取员工的ID集合。
- 遍历员工的ID集合,更新HashMap中对应员工的打卡信息。如果员工已存在于HashMap中,则更新其打卡次数;否则,在HashMap中添加员工的打卡信息,包括第一次打卡的日期和打卡次数。
- 将HashMap中的打卡信息转换为List,并根据打卡次数和第一次打卡日期进行排序。
- 按照题目要求,输出前5名员工的ID。
该算法的时间复杂度为O(N)
,其中N是新员工的数量。因为我们需要遍历30天的打卡信息,并更新HashMap
中的员工打卡信息。排序的时间复杂度为O(NlogN)
,取决于HashMap
转换为List
和List
的排序操作。最终的空间复杂度为O(N)
,取决于HashMap和List的存储空间。
以下是解题思路的Mermaid思维导图: