Skip to content

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);
};

Released under the MIT license