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:
輸入: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] 都是互不相同的。
解題思路
主要存在三種合法區間,分別是[2,5]、[6,9]和[4,7]。比較暴力的做法就是將三個區間中的所有元素存儲為set,然后遍歷reservedSeats將所有同一排的放到同一個set中,最后判斷這些set和前面的區間元素是不是有交集。
注意這里有一個邊界問題,當有一些行并沒有預約座位的時候,我們可以安排兩個家庭。也就是當n大于reservedSeats安排的set個數的時候,要將這些遺漏的部分算上。
class Solution:def maxNumberOfFamilies(self, n: int, reservedSeats: List[List[int]]) -> int:cnt = collections.defaultdict(set)for i, j in reservedSeats:cnt[i].add(j)res = 0q1 = set([2, 3, 4, 5 ,6, 7, 8, 9])q2 = set([2, 3, 4, 5])q3 = set([4, 5, 6, 7])q4 = set([6, 7, 8, 9])for v in cnt.values():if len(v & q1) == 0:res += 2elif len(v & q2) == 0 or len(v & q3) == 0 or len(v & q4) == 0:res += 1return res + (n - len(cnt)) * 2上面代碼我們是通過set實現的交集操作,由于本題中的每一排座位數很少,所以我們也可以通過位運算實現。
class Solution:def maxNumberOfFamilies(self, n: int, reservedSeats: List[List[int]]) -> int:cnt = collections.defaultdict(int)for i, j in reservedSeats:cnt[i] |= 1 << (j - 1)res = 0q1 = int('0111111110', 2)q2 = int('0111100000', 2)q3 = int('0000011110', 2)q4 = int('0001111000', 2)for v in cnt.values():if v & q1 == 0:res += 2elif v & q2 == 0 or v & q3 == 0 or v & q4 == 0:res += 1return res + (n - len(cnt)) * 2我將該問題的其他語言版本添加到了我的GitHub Leetcode
如有問題,希望大家指出!!!
總結
以上是生活随笔為你收集整理的Leetcode 1386:安排电影院座位(超详细的解法!!!)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 高维数据中特征筛选方法的思考总结——多变
- 下一篇: 基于C#在WPF中使用斑马打印机进行打印