1. 问题描述:

如上图所示,电影院的观影厅中有 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 人家庭。

示例 2:

输入:n = 2, reservedSeats = [[2,1],[1,8],[2,6]]
输出:2

示例 3:

输入:n = 4, reservedSeats = [[4,3],[1,4],[4,6],[1,7]]
输出:4

提示:

1 <= n <= 10^9
1 <= reservedSeats.length <= min(10*n, 10^4)
reservedSeats[i].length == 2
1 <= reservedSeats[i][0] <= n
1 <= reservedSeats[i][1] <= 10
所有 reservedSeats[i] 都是互不相同的。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/cinema-seat-allocation

2. 思路分析:

① 一开始想到的是使用哈希表(字典)来记录每一行中被预约的位置,然后遍历记录每一行被预约位置的字典,依次判断有多少个连续的4个位置,从题目中可以知道当第1个位置与第10个位置是否被预约对结果都是没有什么影响的,所以当23456789这8个位置没有被预约的时候说明是这些位置是可以分配给两个家庭的,其余的情况只能够将座位分配给一个家庭:当2345、4567、6789这三种位置只要是满足一种没有被预约的情况那么就可以分配给一个家庭,因为使用的是python语言,所以我们在一开始的时候可以定义三个列表pos1, pos2, pos3 = [2, 3, 4, 5], [4, 5, 6, 7], [6, 7, 8, 9],在遍历字典的值的时候求解字典记录的被预约位置的list列表与上面定义的三个列表的交集来判断属于哪一种的情况,但是提交上去48个例子超时了(一开始的时候没有比较好的思路的情况下可以根据题目的描述模拟整个过程看是否可以解决)

② 在①中的方法超时之后,于是理解了一下力扣官网的题解,题解中使用的是位运算的方法,感觉思路真的是好棒,可以学习学习。分析题目可以知道第1个与第10个位置是否被预约对答案没有什么影响,所以我们可以使用8个二进制位(表示第2-9个位置)来表示哪些位置是被预约的,预约的位置可以标记为1,否则为0,我们可以使用字典来记录每一行中被预约的位置,也就是将预约的位置对应的二进制位置为1,因为第2-9个位置才是有效的(对结果才有影响),而二进制的8个位分别对应着第2-9个位置,所以我们在记录这些被预约的位置的时候需要先将预约的位置减去2(例如二进制的第0位为1表示第2个位置被预约了),然后使用1左移预约的位置减去2的数值那么就可以将被预约位置对应的二进制位置为1,比如第一行的第6个位置被预约了,那么应该将二进制的第4个位置置为1(二进制的位置从低位向高位算起),因为是要记录每一行中所有被预约的位置所以我们要将字典中的值进行或运算,这样可以保证一行中所有被预约的位置都置为1

③ 在②中我们使用字典记录了每一行被预约的位置对应的二进制数字,然后我们就可以遍历字典了,这里定义三个二进制数字,分别为0b11110000, 0b11000011, 0b00001111,这三个数字分别表示2345/4567/6789这些位置是没有被预约的,假如这些二进制数字与字典中每一行被预约位置的二进制数字进行或运算得到的结果还是这些数字说明是可以分配给一个家庭的:说明这些位置是没有被预约的,计数加1即可,此外我们还需要累加每一行中一个位置(可以分配两个家庭)都没有被预约的情况到结果中

总结:使用8位二进制数字表示第2-9个位置的预约情况,所以使用1 << (n - 2)将二进制数字对应的位置置为1(n为被预约的位置),然后将字典中的值对应的二进制数字与当前1左移(n - 2)位得到的数字进行或运算,或运算目的是保持每一行被预约的二进制位都是1

3. 代码如下:

字典(超时):

import collections
from typing import Listclass Solution:def maxNumberOfFamilies(self, n: int, reservedSeats: List[List[int]]) -> int:dic = collections.defaultdict(list)for i in range(len(reservedSeats)):dic[reservedSeats[i][0]].append(reservedSeats[i][1])# print(dic)res = 0pos1, pos2, pos3 = [2, 3, 4, 5], [4, 5, 6, 7], [6, 7, 8, 9]for i in range(n):if i + 1 in dic:pos = dic[i + 1]# 求解出各个集合的交集# 可以分配为两个家庭的情况if len(pos) <= 2 and len(list(set(pos) & set(pos1 + pos3))) == 0:res += 2# 2345/6789的情况elif len(list(set(pos) & set(pos1))) == 0 or len(list(set(pos) & set(pos3))) == 0:res += 1# 6789的情况elif len(list(set(pos) & set(pos2))) == 0:res += 1# 当没有当前的行没有被预约的时候那么结果肯定是加2的return res + 2 * (n - len(dic))

位运算:

import collections
from typing import Listclass Solution:def maxNumberOfFamilies(self, n: int, reservedSeats: List[List[int]]) -> int:res = 0dic = collections.defaultdict(int)# 对应2345/4567/6789三种情况left, middle, right = 0b11110000, 0b11000011, 0b00001111for cur in reservedSeats:# 被预约位置在2-9的范围内才对结果是有影响的if 2 <= cur[1] <= 9:dic[cur[0]] |= (1 << (cur[1] - 2))# 当字典中的值与上面的三个数字异或如果等于上面三个数字说明可以分配一个家庭for value in dic.values():if left | value == left or middle | value == middle or right | value == right:res += 1# 还需要累加那些一行中没有被预约的情况, 这些情况是可以将座位分配给两个家庭的return res + (n - len(dic)) * 2

1386 安排电影院座位(字典、位运算)相关推荐

  1. 1386. 安排电影院座位

    Powered by:NEFU AB-IN Link 文章目录 1386. 安排电影院座位 题意 思路 代码 1386. 安排电影院座位 题意 如上图所示,电影院的观影厅中有 n 行座位,行编号从 1 ...

  2. leetcode 1386. 安排电影院座位 位运算

    题目链接:https://leetcode-cn.com/problems/cinema-seat-allocation/ 在一个电影院里,有n行座位,每行10个,被过道分隔为左边三个中间四个右边三个 ...

  3. leetcode 1386.安排电影院座位

    一.题解 对于每一排座位,被安排家庭数目有四种情况: 1.安排两个家庭,即列2到9都没被预约. 2.安排一个家庭在左边,即2到5没被预约. 3.安排一个家庭在中间,即4到7没被预约. 4.安排一个家庭 ...

  4. 力扣:安排电影院座位

    题目描述 如下图所示,电影院的观影厅中有 n 行座位,行编号从 1 到 n ,且每一行内总共有 10 个座位,列编号从 1 到 10 . 给你数组 reservedSeats ,包含所有已经被预约了的 ...

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

    LeetCode 安排电影院座位 如上图所示,电影院的观影厅中有 n 行座位,行编号从 1 到 n ,且每一行内总共有 10 个座位,列编号从 1 到 10 . 给你数组 reservedSeats ...

  6. Leetcode 1386:安排电影院座位(超详细的解法!!!)

    如上图所示,电影院的观影厅中有 n 行座位,行编号从 1 到 n ,且每一行内总共有 10 个座位,列编号从 1 到 10 . 给你数组 reservedSeats ,包含所有已经被预约了的座位.比如 ...

  7. 秋招每日一题T32——安排电影院座位

    题目描述 如上图所示,电影院的观影厅中有 n 行座位,行编号从 1 到 n ,且每一行内总共有 10 个座位,列编号从 1 到 10 . 给你数组 reservedSeats ,包含所有已经被预约了的 ...

  8. LeetCode题解(1386):安排电影院座位(Python)

    题目:原题链接(中等) 标签:贪心算法.数组 解法 时间复杂度 空间复杂度 执行用时 Ans 1 (Python) O(R)O(R)O(R) O(R)O(R)O(R) 144ms (41.56%) A ...

  9. leetcode1386. 安排电影院座位(贪心)

    如上图所示,电影院的观影厅中有 n 行座位,行编号从 1 到 n ,且每一行内总共有 10 个座位,列编号从 1 到 10 . 给你数组 reservedSeats ,包含所有已经被预约了的座位.比如 ...

  10. (Python)LeetCode1386:安排电影院座位

    题目 如上图所示,电影院的观影厅中有 n 行座位,行编号从 1 到 n ,且每一行内总共有 10 个座位,列编号从 1 到 10 . 给你数组 reservedSeats ,包含所有已经被预约了的座位 ...

最新文章

  1. 团队分数分配方法——BY 李栋
  2. HTTPS是如何加密的
  3. Vagrant安装centos7时一直报错无法保存文件
  4. Delphi连接AutoCAD_计算任意线条的长度宏的嵌套
  5. 字符串相似度算法——Levenshtein Distance算法
  6. 【Java学习笔记八】包装类和vector
  7. 从KPI到OKR,高阶产品人如何推动业务高速增长
  8. 用 State Pattern 来实现一个简单的 状态机
  9. Kafka使用经验小结
  10. oracle into 循环,oracle游标中使用select into查询结果为NULL导致异常提前退出循环——菜鸟解决办法(^_^)...
  11. 从零基础入门Tensorflow2.0 ----九、44.4 签名函数转换成savedmodel
  12. 推荐系统实践 - 基于用户行为分析的推荐算法
  13. 《软件工程导论》之总体设计
  14. Word文件的OpenXML解析(以Python3为例)
  15. [案例4-6]研究生薪资管理
  16. 从Uniswap v3来看新的期权范式?
  17. 旧电脑很卡怎么重新安装电脑系统?
  18. Java基础面试 --序列化,反射,拷贝
  19. 流量变现:推广渠道 + 货源
  20. Spark Partitioning on Disk with partitionBy

热门文章

  1. 一个小型的汇编编译器
  2. 继电器学习笔记(一)继电器概念
  3. 为什么仿宋字体打印出楷体_win7仿宋字体及楷体字体打包下载
  4. 最优化理论与算法(袁亚湘)学习笔记---最优性条件和最优化算法的基本结构
  5. 详细了解DAS、SAN和NAS三种存储方式
  6. 软件介绍——SyncToy 微软官方文件同步工具
  7. EMBER-网络安全恶意软件公开数据集,论文的翻译,自己的笔记
  8. “磁碟机”病毒疫情紧急!已有超过5万台电脑被感染
  9. 关于LIS系统与HIS系统的接口方案
  10. 如何解决速达软件出现主键、单号、编码相同的报错