连续空余座位:相邻的空座才算
LeetCode 603 · LAG/LEAD、自连接、连续判断
面试怎么回答
先过滤出空座,再用 LAG/LEAD 取前后空座的编号,只要和前一个或后一个正好差 1 就是连续空座。自连接写法是 ABS(a.seat_id - b.seat_id) = 1 且两边都空,结果需要 DISTINCT。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
题意
影院座位表记录了每个座位是否空闲。找出所有属于「至少两个相邻空座」的空座位编号,按编号排序。
表结构
- cinema:seat_id(主键,自增)、free(1 空闲,0 已占)
思路
先只保留空座,再看它前一个或后一个空座的编号是否正好相邻(差 1)。原解法在空座中用 LAG/LEAD 取前后座位编号,任一侧相邻就保留。也可以用自连接:两个空座编号差的绝对值为 1。
参考解法
select seat_id
from (
select seat_id,
lag(seat_id,1,-99) over(order by seat_id) ls,
lead(seat_id,1,-99) over(order by seat_id) rs
from cinema
where free=1
)t1
where seat_id-ls = 1 or rs-seat_id =1
另一种写法:自连接写法
SELECT DISTINCT a.seat_id
FROM cinema a
JOIN cinema b ON ABS(a.seat_id - b.seat_id) = 1 AND a.free = 1 AND b.free = 1
ORDER BY a.seat_id
易错点
- 先 LAG/LEAD 再过滤空座的话,前后行可能是被占的座位,要先过滤再取相邻。