1349. Maximum Students Taking Exam
Description
Given a m * n
matrix seats
that represent seats distributions in a classroom. If a seat is broken, it is denoted by '#'
character otherwise it is denoted by a '.'
character.
Students can see the answers of those sitting next to the left, right, upper left and upper right, but he cannot see the answers of the student sitting directly in front or behind him. Return the maximum number of students that can take the exam together without any cheating being possible.
Students must be placed in seats in good condition.
Example 1:
Input: seats = [["#",".","#","#",".","#"], [".","#","#","#","#","."], ["#",".","#","#",".","#"]] Output: 4 Explanation: Teacher can place 4 students in available seats so they don't cheat on the exam.
Example 2:
Input: seats = [[".","#"], ["#","#"], ["#","."], ["#","#"], [".","#"]] Output: 3 Explanation: Place all students in available seats.
Example 3:
Input: seats = [["#",".",".",".","#"], [".","#",".","#","."], [".",".","#",".","."], [".","#",".","#","."], ["#",".",".",".","#"]] Output: 10 Explanation: Place students in available seats in column 1, 3 and 5.
Constraints:
seats
contains only characters'.'
'#'.
m == seats.length
n == seats[i].length
1 <= m <= 8
1 <= n <= 8
Solutions
Solution: Dynamic Programming
- Time complexity: O(m*22n)
- Space complexity: O(m+2n)
JavaScript
js
/**
* @param {character[][]} seats
* @return {number}
*/
const maxStudents = function (seats) {
const BROKEN_SEAT = '#';
const m = seats.length;
const n = seats[0].length;
const brokenMask = Array.from({ length: m }, () => 0);
for (let row = 0; row < m; row++) {
for (let col = 0; col < n; col++) {
const seat = seats[row][col];
if (seat !== BROKEN_SEAT) continue;
brokenMask[row] |= 1 << col;
}
}
const maxMask = 1 << n;
const maskCount = Array.from({ length: maxMask }, () => 0);
for (let mask = 0; mask < maxMask; mask++) {
maskCount[mask] = maskCount[mask >> 1] + (mask & 1);
}
let dp = Array.from({ length: maxMask }, () => 0);
for (let row = 0; row < m; row++) {
const nextDp = Array.from({ length: maxMask }, () => 0);
for (let mask = 0; mask < maxMask; mask++) {
if (mask & (mask << 1)) continue;
if (mask & brokenMask[row]) continue;
for (let prevMask = 0; prevMask < maxMask; prevMask++) {
const prev = (prevMask << 1) | (prevMask >> 1);
if (mask & prev) continue;
nextDp[mask] = Math.max(dp[prevMask] + maskCount[mask], nextDp[mask]);
}
}
dp = nextDp;
}
return Math.max(...dp);
};