LeetCode
安排电影院座位
如上图所示,电影院的观影厅中有 n 行座位,行编号从 1 到 n ,且每一行内总共有 10 个座位,列编号从 1 到 10 。
给你数组 reservedSeats ,包含所有已经被预约了的座位。比如说,researvedSeats[i]=[3,8] ,它表示第 3 行第 8 个座位被预约了。
请你返回 最多能安排多少个 4 人家庭 。4 人家庭要占据 同一行内连续 的 4 个座位。隔着过道的座位(比方说 [3,3] 和 [3,4])不是连续的座位,但是如果你可以将 4 人家庭拆成过道两边各坐 2 人,这样子是允许的。
示例 1:
输入:n = 3, reservedSeats = [[1,2],[1,3],[1,8],[2,6],[3,1],[3,10]]
输出:4
解释:上图所示是最优的安排方案,总共可以安排 4 个家庭。蓝色的叉表示被预约的座位,橙色的连续座位表示一个 4 人家庭。
解法:位运算判断
解题思路: 其实思路很简单,每行最多能容纳两个四人家庭,而第一个位置跟最后一个位置并不会对结果造成影响
所以我们用一个8位的数字来进行判断,当第i个位置被预定之后,我们就将i-2位的数字变成1,没被预定即为0,然后将该数字跟当前行用一个哈希表联系起来
当预定数字全部遍历完之后,我们只要取出哈希表中的值进行以下操作即可判断是否能容纳四人家庭
- 跟11110000按位或计算,如果结果仍是11110000,说明四个0的位置可以容纳一个四人家庭
- 跟11000011按位或计算,同理
- 跟00001111按位或计算,同理
完整代码:
class Solution {
public int maxNumberOfFamilies(int n, int[][] reservedSeats) {
int left = 0b11110000;
int middle = 0b11000011;
int right = 0b00001111;
Map <Integer, Integer> occupied = new HashMap <Integer, Integer> ();
for (int[] seat: reservedSeats) {
if (seat[1] >= 2 && seat[1] <= 9) {
int origin = occupied.containsKey(seat[0]) ? occupied.get(seat[0]) : 0;
int value = origin | (1 << (seat[1] - 2));
occupied.put(seat[0], value);
}
}
int ans = (n - occupied.size()) * 2;
//seat[1] = 1 || seat[1] = 10的就是坐两组家庭的,他们不会出现在哈希表中
for (Map.Entry <Integer, Integer> entry : occupied.entrySet()) {
int row = entry.getKey(), bitmask = entry.getValue();
if (((bitmask | left) == left) || ((bitmask | middle) == middle) || ((bitmask | right) == right)) {
++ans; // 每一排座位只能坐一组家庭,因为出现在哈希表表示在[2,9]至少有一个座位被预约了
}
}
return ans;
}
}
心得体会
其实看到这道题我就觉得挺简单的,但是没想到用哈希表和按位或计算来简化代码,用了一大堆if语句,后面受不了了就看了题解
题目和解法来源
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/cinema-seat-allocation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。