当前位置: 首页 > news >正文

位运算题目:安排电影院座位

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 解法
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:安排电影院座位

出处:1386. 安排电影院座位

难度

7 级

题目描述

要求

示例 0

电影院的观影厅中有 n \texttt{n} n 行座位,行编号从 1 \texttt{1} 1 n \texttt{n} n,每一行有 10 \texttt{10} 10 个座位,列编号从 1 \texttt{1} 1 10 \texttt{10} 10。如上图所示。

给定数组 reservedSeats \texttt{reservedSeats} reservedSeats,包含所有已经被预约了的座位。例如, researvedSeats[i] = [3,8] \texttt{researvedSeats[i] = [3,8]} researvedSeats[i] = [3,8] 表示第 3 \texttt{3} 3 行第 8 \texttt{8} 8 个座位被预约了。

返回可以安排入座的四人家庭的最大数量。四人家庭要占据同一行的连续四个座位。隔着过道的座位(例如 [3,3] \texttt{[3,3]} [3,3] [3,4] \texttt{[3,4]} [3,4])不是连续的座位,但是如果可以将四人家庭拆成过道两边各坐两人,也是允许的。

示例

示例 1:

示例 1

输入: n = 3, reservedSeats = [[1,2],[1,3],[1,8],[2,6],[3,1],[3,10]] \texttt{n = 3, reservedSeats = [[1,2],[1,3],[1,8],[2,6],[3,1],[3,10]]} n = 3, reservedSeats = [[1,2],[1,3],[1,8],[2,6],[3,1],[3,10]]
输出: 4 \texttt{4} 4
解释:上图所示是最优的安排方案,总共可以安排 4 \texttt{4} 4 个四人家庭。蓝色的叉表示被预约的座位,橙色的连续座位表示一个四人家庭。

示例 2:

输入: n = 2, reservedSeats = [[2,1],[1,8],[2,6]] \texttt{n = 2, reservedSeats = [[2,1],[1,8],[2,6]]} n = 2, reservedSeats = [[2,1],[1,8],[2,6]]
输出: 2 \texttt{2} 2

示例 3:

输入: n = 4, reservedSeats = [[4,3],[1,4],[4,6],[1,7]] \texttt{n = 4, reservedSeats = [[4,3],[1,4],[4,6],[1,7]]} n = 4, reservedSeats = [[4,3],[1,4],[4,6],[1,7]]
输出: 4 \texttt{4} 4

数据范围

  • 1 ≤ n ≤ 10 9 \texttt{1} \le \texttt{n} \le \texttt{10}^\texttt{9} 1n109
  • 1 ≤ reservedSeats.length ≤ min(10 × n, 10 4 ) \texttt{1} \le \texttt{reservedSeats.length} \le \texttt{min(10} \times \texttt{n, 10}^\texttt{4}\texttt{)} 1reservedSeats.lengthmin(10×n, 104)
  • reservedSeats[i].length = 2 \texttt{reservedSeats[i].length} = \texttt{2} reservedSeats[i].length=2
  • 1 ≤ reservedSeats[i][0] ≤ n \texttt{1} \le \texttt{reservedSeats[i][0]} \le \texttt{n} 1reservedSeats[i][0]n
  • 1 ≤ reservedSeats[i][1] ≤ 10 \texttt{1} \le \texttt{reservedSeats[i][1]} \le \texttt{10} 1reservedSeats[i][1]10
  • 所有 reservedSeats[i] \texttt{reservedSeats[i]} reservedSeats[i] 各不相同

解法

思路和算法

由于电影院的座位行数 n n n 的最大值是 1 0 9 10^9 109,因此不能遍历电影院座位的每一行,而是需要根据已经被预约的座位计算可以安排入座的四人家庭的最大数量。

由于电影院座位的每一行有 10 10 10 个座位,因此对于每一行可以使用一个二进制数 mask \textit{mask} mask 表示该行被预约的座位。由于座位编号是 1 1 1 10 10 10,因此 mask \textit{mask} mask 使用 11 11 11 位二进制数表示,对于 1 ≤ i ≤ 10 1 \le i \le 10 1i10 mask \textit{mask} mask 的从低到高的第 i i i 位表示该行编号为 i i i 的座位是否被预约, 1 1 1 表示被预约, 0 0 0 表示未被预约, mask \textit{mask} mask 的最低位一定是 0 0 0,因为没有编号为 0 0 0 的座位。遍历数组 reservedSeats \textit{reservedSeats} reservedSeats 之后即可得到每一行被预约的座位,使用哈希表记录数组 reservedSeats \textit{reservedSeats} reservedSeats 中出现的每一行对应的 mask \textit{mask} mask

对于没有在哈希表中出现的行,每一行的所有座位都未被预约,因此该行最多可以安排两个四人家庭入座。对于在哈希表中出现的行,每一行考虑两种安排四人家庭入座的方案,一是将左边座位 2 2 2 5 5 5 和右边座位 6 6 6 9 9 9 各安排一个四人家庭入座,二是将中间座位 4 4 4 7 7 7 安排一个四人家庭入座。

对于第一种方案,如果座位 2 2 2 5 5 5 都未被预约则可以安排一个四人家庭入座左边座位,如果座位 6 6 6 9 9 9 都未被预约则可以安排一个四人家庭入座右边座位,分别判断左边座位和右边座位是否可以安排四人家庭入座,得到可以安排入座的四人家庭数。

对于第二种方案,如果座位 4 4 4 7 7 7 都未被预约则可以安排一个四人家庭入座中间座位,判断中间座位是否可以安排四人家庭入座,得到可以安排入座的四人家庭数。

两种方案中取可以安排入座的四人家庭数的最大值,即为该行可以安排入座的四人家庭数的最大值。

遍历所有在哈希表中出现的行之后,即可得到整个电影院可以安排入座的四人家庭的最大数量。

对于每一行计算两种方案下可以安排入座的四人家庭数都可以使用位运算实现。具体做法是定义三个常量 MASK_LEFT \textit{MASK\_LEFT} MASK_LEFT MASK_RIGHT \textit{MASK\_RIGHT} MASK_RIGHT MASK_MIDDLE \textit{MASK\_MIDDLE} MASK_MIDDLE 分别表示左边座位、右边座位和中间座位的二进制表示。将该行对应的 mask \textit{mask} mask 按位取反之后分别和每个常量计算按位与的结果,如果结果等于该常量本身则表示可以安排一个四人家庭入座该常量对应的四个座位。例如,如果 mask \textit{mask} mask 按位取反之后和 MASK_LEFT \textit{MASK\_LEFT} MASK_LEFT 按位与的结果等于 MASK_LEFT \textit{MASK\_LEFT} MASK_LEFT,则表示左边座位(即座位 2 2 2 5 5 5)可以安排一个四人家庭入座。

代码

class Solution {public int maxNumberOfFamilies(int n, int[][] reservedSeats) {final int MASK_LEFT = 0b00000111100;final int MASK_RIGHT = 0b01111000000;final int MASK_MIDDLE = 0b00011110000;Map<Integer, Integer> masks = new HashMap<Integer, Integer>();for (int[] reservedSeat : reservedSeats) {int row = reservedSeat[0], label = reservedSeat[1];masks.put(row, masks.getOrDefault(row, 0) | (1 << label));}int total = 2 * (n - masks.size());Set<Map.Entry<Integer, Integer>> entries = masks.entrySet();for (Map.Entry<Integer, Integer> entry : entries) {int mask = entry.getValue();int count1 = 0, count2 = 0;if ((~mask & MASK_LEFT) == MASK_LEFT) {count1++;}if ((~mask & MASK_RIGHT) == MASK_RIGHT) {count1++;}if ((~mask & MASK_MIDDLE) == MASK_MIDDLE) {count2++;}total += Math.max(count1, count2);}return total;}
}

复杂度分析

  • 时间复杂度: O ( m ) O(m) O(m),其中 m m m 是数组 reservedSeats \textit{reservedSeats} reservedSeats 的长度。需要遍历每个被预约的座位计算每一行对应的二进制数并存入哈希表,然后遍历哈希表根据每一行对应的二进制数计算可以安排入座的四人家庭的最大数量,由于遍历每个被预约的座位以及遍历哈希表中的每一行的操作的时间都是 O ( 1 ) O(1) O(1),因此时间复杂度是 O ( m ) O(m) O(m)

  • 空间复杂度: O ( m ) O(m) O(m),其中 m m m 是数组 reservedSeats \textit{reservedSeats} reservedSeats 的长度。空间复杂度主要取决于哈希表,哈希表中的记录数不超过 m m m

相关文章:

  • 编专利或委托他人编专利属于学术不端行为吗?
  • crawl4ai能替代scrapy等传统爬虫框架吗?
  • 【报错】view size is not compatible with input tensor‘s size and stride
  • 编译原理头歌实验:词法分析程序设计与实现(C语言版)
  • Oracle OCP认证考试考点详解083系列12
  • SpringBoot中使用MCP和通义千问来处理和分析数据-连接本地数据库并生成实体类
  • 15前端项目----用户信息/导航守卫
  • SNMP 协议介绍、开发方法及示例
  • 【造包工具】【Xcap】精讲Xcap构造分片包(IPv4、ipv6、4G\5G等pcap均可),图解超赞超详细!!!
  • 投资逻辑与未来风险:高端PCB的黄金周期能持续多久?
  • 【Linux网络】网络命令
  • mongodb升级、改单节点模式
  • 矢量网络分析仪测驻波比:从原理到实战操作全解析
  • Nacos源码—6.Nacos升级gRPC分析一
  • 【redis】分片方案
  • 数据结构(二)——线性表的链式表示和实现
  • 关键字where
  • STM32智能刷卡消费系统(uC/OS-III)
  • LeetCode 11.盛最多水的容器 (Java)
  • CBO和HBO区别及介绍
  • 做游戏出租的网站好/互联网推广渠道
  • 网站建设推广哪里实惠/seo搜索引擎优化到底是什么
  • 房地产定制开发/seo简单速排名软件
  • 顺德做网站公司哪家好/推广代理登录页面
  • 医院电子网站建设/查域名备案信息查询
  • 做网站一定要用云解析吗/2022拉新推广赚钱的app