安排电影院座位--贪心算法

本文介绍了一道LeetCode上的题目——安排电影院座位,探讨如何使用贪心算法和位运算判断来解决如何容纳最多的4人家庭。通过建立哈希表记录座位状态,并进行按位或运算,来判断每行能否容纳四人家庭。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值