603. 连续空余座位 🔒
题目描述
表: Cinema
+-------------+------+ | Column Name | Type | +-------------+------+ | seat_id | int | | free | bool | +-------------+------+ Seat_id 是该表的自动递增主键列。 在 PostgreSQL 中,free 存储为整数。请使用 ::boolean 将其转换为布尔格式。 该表的每一行表示第 i 个座位是否空闲。1 表示空闲,0 表示被占用。
查找电影院所有连续可用的座位。
返回按 seat_id 升序排序 的结果表。
测试用例的生成使得两个以上的座位连续可用。
结果表格式如下所示。
示例 1:
输入: Cinema 表: +---------+------+ | seat_id | free | +---------+------+ | 1 | 1 | | 2 | 0 | | 3 | 1 | | 4 | 1 | | 5 | 1 | +---------+------+ 输出: +---------+ | seat_id | +---------+ | 3 | | 4 | | 5 | +---------+
解法
方法一:自连接
思考
空座需与左右至少一侧相邻且亦空。对每个座位再查邻居可用相关子查询,但会重复探邻。
自连接 ABS(id 差)=1 且两侧都 free,自然得到所有「有空邻座」的座位,去重后即答案。
我们可以使用自连接的方式,将相邻的两个座位连接起来,然后筛选出连续空余的座位并去重排序即可。
1 2 3 4 5 6 | |
方法二:窗口函数
思考
自连接会生成配对行。窗口 LAG/LEAD 可在一行内读到前后座位的 free,若自身与前或后之和为 \(2\),则该座属于连续空座。
我们也可以使用 LAG 和 LEAD 函数(或者 SUM() OVER(ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING))来获取相邻的座位信息,然后筛选出连续空余的座位并去重排序即可。
1 2 3 4 5 6 7 8 9 10 11 12 | |
方法三
思考
亦可不对前后分别取 LAG/LEAD,而用 SUM(free) OVER (ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) 一次看三连。当前座空且窗口和大于 \(1\),说明邻座至少一个为空。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |