LeetCode 1280. 学生们参加各科测试的次数

题目描述

1280. 学生们参加各科测试的次数

思路分析

解法一:哈希计数 + 笛卡尔积(推荐)

核心思路

  • 统计每个 (studentId, subject) 的考试次数。
  • 对所有学生与科目做笛卡尔积输出。
  • 若无记录则次数为 0。


复杂度分析

  • 时间复杂度:O(S * U + E),其中 S 为学生数,U 为科目数,E 为考试记录数。
  • 空间复杂度:O(E),存储计数映射。
class Solution {
    static class Student {
        int id;
        String name;
    }

    static class Exam {
        int studentId;
        String subject;
    }

    static class Result {
        int studentId;
        String studentName;
        String subjectName;
        int attended;
    }

    public List<Result> studentsAndExams(List<Student> students, List<String> subjects, List<Exam> exams) {
        Map<Integer, String> nameMap = new HashMap<>();
        for (Student s : students) {
            nameMap.put(s.id, s.name);
        }

        Map<Integer, Map<String, Integer>> cnt = new HashMap<>();
        for (Exam e : exams) {
            cnt.computeIfAbsent(e.studentId, k -> new HashMap<>())
                    .merge(e.subject, 1, Integer::sum);
        }

        students.sort(Comparator.comparingInt(a -> a.id));
        Collections.sort(subjects);

        List<Result> res = new ArrayList<>();
        for (Student s : students) {
            for (String sub : subjects) {
                int times = cnt.getOrDefault(s.id, Collections.emptyMap()).getOrDefault(sub, 0);
                Result r = new Result();
                r.studentId = s.id;
                r.studentName = s.name;
                r.subjectName = sub;
                r.attended = times;
                res.add(r);
            }
        }

        return res;
    }
}
type Student struct {
	ID   int
	Name string
}

type Exam struct {
	StudentID int
	Subject   string
}

type Result struct {
	StudentID   int
	StudentName string
	SubjectName string
	Attended    int
}

func studentsAndExams(students []Student, subjects []string, exams []Exam) []Result {
	cnt := make(map[int]map[string]int)
	for _, e := range exams {
		if _, ok := cnt[e.StudentID]; !ok {
			cnt[e.StudentID] = make(map[string]int)
		}
		cnt[e.StudentID][e.Subject]++
	}

	sort.Slice(students, func(i, j int) bool { return students[i].ID < students[j].ID })
	sort.Strings(subjects)

	res := make([]Result, 0)
	for _, s := range students {
		for _, sub := range subjects {
			times := 0
			if m, ok := cnt[s.ID]; ok {
				times = m[sub]
			}
			res = append(res, Result{
				StudentID:   s.ID,
				StudentName: s.Name,
				SubjectName: sub,
				Attended:    times,
			})
		}
	}

	return res
}

相似题目

题目 难度 考察点
1075. 项目员工 I 简单 分组统计
1141. 查询近30天活跃用户数 中等 分组统计
1204. 最后一个能进入电梯的人 中等 排序
1280. 学生们参加各科测试的次数 简单 计数
1527. 患某种疾病的患者 简单 过滤
本文作者:
本文链接: https://hgnulb.github.io/blog/2024/57883384
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!