LeetCode-1386 安排电影院座位
LeetCode-1386 安排电影院座位
题目描述
如上图所示,电影院的观影厅中有 $n$ 行座位,行编号从 $1$到 $n$ ,且每一行内总共有 $10$ 个座位,列编号从 $1$ 到 $10$ 。
给你数组 reservedSeats
,包含所有已经被预约了的座位。比如说,researvedSeats[i]=[3,8]
,它表示第 $3$ 行第 $8$ 个座位被预约了。
请你返回 最多能安排多少个 $4$ 人家庭 。$4$ 人家庭要占据 同一行内连续 的 $4$ 个座位。隔着过道的座位(比方说 $[3,3]$ 和 $[3,4]$)不是连续的座位,但是如果你可以将 $4$ 人家庭拆成过道两边各坐 $2$ 人,这样子是允许的。
示例 1:
1 | 输入:n = 3, reservedSeats = [[1,2],[1,3],[1,8],[2,6],[3,1],[3,10]] |
示例 2:
1 | 输入:n = 2, reservedSeats = [[2,1],[1,8],[2,6]] |
示例 3:
1 | 输入:n = 4, reservedSeats = [[4,3],[1,4],[4,6],[1,7]] |
位运算 - $O(N)$
二进制表示
我们观察发现所有满足条件的家庭座位如下:
- 红色方框 分别表示三种符合条件的家庭座位
- 两侧两个座位紫色方框不会构成家庭座位
问题转换成:判断给定的座位每一行是否存在上述三种情况即可
如果我们用 $0/1$ 分别对每个座位是否预定进行标记,那么每一排座位可以看成一个二进制串:
- $0$ 表示 没有 被预定
- $1$ 表示被预定了
由于两侧位置不会构成家庭座位,因此直接忽略即可
位运算
此时,我们对 上述三种符合条件的家庭座位 分别用二进制串进行表述:
我们得到了三种符合条件的家庭座位对应的二进制串:
- $00001111$
- $11110000$
- $11000011$
那么:如果我们也将 问题给定的每一行座位利用同样的方式进行标记得到一个二进制串 $v$,那么每一行座位是否存在上述三种符合条件情况等价于:
- 符合 $00001111$ 这种情况等价于:$v$ 的前 $4$ 位是否均是 $0$
- 符合 $11110000$ 这种情况等价于:$v$ 的后 $4$ 位是否均是 $0$
- 符合 $11000011$ 这种情况等价于:$v$ 的中间 $4$ 位是否均是 $0$
获取一个二进制某些位置的数值我们可以利用 与 运算:
算法流程
- 依次计算问题给定座位的每一行座位的家庭座位数量,最后累加
- 两侧两个位置由于均不会构成家庭座位,因此忽略掉
- 当前行利用二进制进行表示为 $v$
- 如果当前行不存在任何预定的位置,则当前行家庭数量为 $2$
- 如果存在预定位置:可以知道三种符合条件最多符合其中 $1$ 种
- 分别获取对应位置二进制串:
11110000 & v, 11110000 & v, 001111 & v
- 如果这三个值,存在一个 $0$,则说明符合三种状态的某个,当前行家庭数量为 $1$
- 分别获取对应位置二进制串:
时间复杂度 - $O(N)$
- 由于要枚举
reservedSeats
数组,复杂度为 $O(N)$,其中 $N$ 为reservedSeats
数组长度。
代码
1 | func maxNumberOfFamilies(n int, reservedSeats [][]int) int { |
1 | class Solution { |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Cat's Blog!
评论