Maximum Compatibility Score Sum
MedPrompt
There is a survey that consists of n questions where each question's answer is either 0 (no) or 1 (yes).
The survey was given to m students numbered from 0 to m - 1 and m mentors numbered from 0 to m - 1. The answers of the students are represented by a 2D integer array students where students[i] is an integer array that contains the answers of the ith student (0-indexed). The answers of the mentors are represented by a 2D integer array mentors where mentors[j] is an integer array that contains the answers of the jth mentor (0-indexed).
Each student will be assigned to one mentor, and each mentor will have one student assigned to them. The compatibility score of a student-mentor pair is the number of answers that are the same for both the student and the mentor.
- For example, if the student's answers were
[1, 0, 1]and the mentor's answers were[0, 0, 1], then their compatibility score is 2 because only the second and the third answers are the same.
You are tasked with finding the optimal student-mentor pairings to maximize the sum of the compatibility scores.
Given students and mentors, return the maximum compatibility score sum that can be achieved.
Example 1:
Input: students = [[1,1,0],[1,0,1],[0,0,1]], mentors = [[1,0,0],[0,0,1],[1,1,0]]
Output: 8
Explanation: We assign students to mentors in the following way:
- student 0 to mentor 2 with a compatibility score of 3.
- student 1 to mentor 0 with a compatibility score of 2.
- student 2 to mentor 1 with a compatibility score of 3.
The compatibility score sum is 3 + 2 + 3 = 8.Example 2:
Input: students = [[0,0],[0,0],[0,0]], mentors = [[1,1],[1,1],[1,1]]
Output: 0
Explanation: The compatibility score of any student-mentor pair is 0.
Constraints:
m == students.length == mentors.lengthn == students[i].length == mentors[j].length1 <= m, n <= 8students[i][k]is either0or1.mentors[j][k]is either0or1.
Approaches
3 approaches with complexity analysis and trade-offs.
The problem asks for an optimal pairing between students and mentors to maximize the total compatibility score. Since each of the m students must be paired with a unique mentor from the m available mentors, any valid pairing corresponds to a permutation of the mentors. The brute-force approach is to generate every possible permutation of mentors, calculate the total score for each permutation, and find the maximum among them. This can be implemented using a recursive backtracking algorithm that explores all possible assignments.
Algorithm
- Pre-computation: First, it's helpful to pre-compute the compatibility scores for every possible student-mentor pair and store them in an
m x mmatrix, let's call itscores.scores[i][j]will hold the score for studentiand mentorj. This takesO(m*m*n)time. - Backtracking Function: Define a recursive function, for example,
backtrack(studentIndex, currentScore). This function will try to assign a mentor tostudentIndex. - State: The state of the recursion is defined by the
studentIndexwe are currently considering and the set of mentors who have already been assigned. We can use a boolean array,visitedMentors, to keep track of used mentors. - Base Case: The recursion stops when
studentIndexequalsm, which means all students have been assigned a mentor. At this point, we compare thecurrentScorewith a global maximum score and update it if thecurrentScoreis higher. - Recursive Step: For the current
studentIndex, we iterate through all available mentors (jfrom0tom-1). Ifmentors[j]has not been visited:- Mark
mentors[j]as visited. - Add the score
scores[studentIndex][j]tocurrentScore. - Make a recursive call for the next student:
backtrack(studentIndex + 1, newCurrentScore). - After the recursive call returns, we backtrack by un-marking
mentors[j]as visited and subtracting the score. This allows us to explore other possible assignments forstudentIndex.
- Mark
Walkthrough
This approach systematically explores every single possible assignment of students to mentors. We can think of this as building an assignment one student at a time.
class Solution { int maxScore = 0; public int maxCompatibilitySum(int[][] students, int[][] mentors) { int m = students.length; int n = students[0].length; // Pre-compute scores for all student-mentor pairs int[][] scores = new int[m][m]; for (int i = 0; i < m; i++) { for (int j = 0; j < m; j++) { int score = 0; for (int k = 0; k < n; k++) { if (students[i][k] == mentors[j][k]) { score++; } } scores[i][j] = score; } } boolean[] visitedMentors = new boolean[m]; backtrack(0, 0, scores, visitedMentors); return maxScore; } private void backtrack(int studentIndex, int currentScore, int[][] scores, boolean[] visitedMentors) { int m = scores.length; if (studentIndex == m) { maxScore = Math.max(maxScore, currentScore); return; } // Iterate through all mentors for the current student for (int mentorIndex = 0; mentorIndex < m; mentorIndex++) { if (!visitedMentors[mentorIndex]) { // Choose visitedMentors[mentorIndex] = true; // Recurse backtrack(studentIndex + 1, currentScore + scores[studentIndex][mentorIndex], scores, visitedMentors); // Unchoose (Backtrack) visitedMentors[mentorIndex] = false; } } }}Complexity
Time
O(m^2 * n + m! * m). The pre-computation of the `scores` matrix takes `O(m * m * n)`. The backtracking part explores `m!` permutations. For each permutation, we do `m` additions to calculate the total score, but in our recursive implementation, the additions are done along the path. The number of nodes in the recursion tree is on the order of `m!`, leading to a time complexity of `O(m! * m)`. The total time is the sum of these two parts.
Space
O(m^2). We need `O(m^2)` space for the pre-computed `scores` matrix. The recursion depth is `m`, and we use a boolean array of size `m`, so the space for recursion is `O(m)`. Thus, the total space is dominated by the scores matrix.
Trade-offs
Pros
It is guaranteed to find the optimal solution because it checks every possibility.
The logic is relatively straightforward to understand and implement.
Cons
The time complexity is
O(m!), which is very high and only feasible for very small values ofm(likem <= 8in this problem).It explores many redundant paths, which is improved upon by dynamic programming.
Solutions
Solution
class Solution {private int[][] g;private boolean[] vis;private int m;private int ans;public int maxCompatibilitySum(int[][] students, int[][] mentors) { m = students.length; g = new int[m][m]; vis = new boolean[m]; for (int i = 0; i < m; ++i) { for (int j = 0; j < m; ++j) { for (int k = 0; k < students[i].length; ++k) { g[i][j] += students[i][k] == mentors[j][k] ? 1 : 0; } } } dfs(0, 0); return ans; }private void dfs(int i, int t) { if (i == m) { ans = Math.max(ans, t); return; } for (int j = 0; j < m; ++j) { if (!vis[j]) { vis[j] = true; dfs(i + 1, t + g[i][j]); vis[j] = false; } } }}Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.