zoukankan      html  css  js  c++  java
  • [LeetCode] 1386. Cinema Seat Allocation

    A cinema has n rows of seats, numbered from 1 to n and there are ten seats in each row, labelled from 1 to 10 as shown in the figure above.

    Given the array reservedSeats containing the numbers of seats already reserved, for example, reservedSeats[i] = [3,8] means the seat located in row 3 and labelled with 8 is already reserved.

    Return the maximum number of four-person groups you can assign on the cinema seats. A four-person group occupies four adjacent seats in one single row. Seats across an aisle (such as [3,3] and [3,4]) are not considered to be adjacent, but there is an exceptional case on which an aisle split a four-person group, in that case, the aisle split a four-person group in the middle, which means to have two people on each side.

    Example 1:

    Input: n = 3, reservedSeats = [[1,2],[1,3],[1,8],[2,6],[3,1],[3,10]]
    Output: 4
    Explanation: The figure above shows the optimal allocation for four groups, where seats mark with blue are already reserved and contiguous seats mark with orange are for one group.
    

    Example 2:

    Input: n = 2, reservedSeats = [[2,1],[1,8],[2,6]]
    Output: 2
    

    Example 3:

    Input: n = 4, reservedSeats = [[4,3],[1,4],[4,6],[1,7]]
    Output: 4

    Constraints:

    • 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
    • All reservedSeats[i] are distinct.

    安排电影院座位。

    如上图所示,电影院的观影厅中有 n 行座位,行编号从 1 到 n ,且每一行内总共有 10 个座位,列编号从 1 到 10 。

    给你数组 reservedSeats ,包含所有已经被预约了的座位。比如说,researvedSeats[i]=[3,8] ,它表示第 3 行第 8 个座位被预约了。

    请你返回 最多能安排多少个 4 人家庭 。4 人家庭要占据 同一行内连续 的 4 个座位。隔着过道的座位(比方说 [3,3] 和 [3,4])不是连续的座位,但是如果你可以将 4 人家庭拆成过道两边各坐 2 人,这样子是允许的。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/cinema-seat-allocation
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    思路是贪心 + 位运算。这里贪心的原则是对于每一行row,我们优先查看是否能满足两个家庭,如果实在不满足,我们再看是否能满足一个家庭。具体的做法是,我们创建一个hashmap<Integer, Integer>,key代表当前扫描的行row,value代表这一行已经被reserve的座位。当在同一行中有多行被reserve的时候,我们通过把1左移col个位置来记录,比如当前行的第一个位子和第二个位子被reserve了,我们就把1左移一位的结果和把1左移两位的结果做OR操作。

    之后我们再次遍历hashmap的keyset(),这里遍历的思路是对于每一行row,我们来查看到底能满足多少个家庭。根据条件,虽然座位号是从1到10,但是位置1和10是否坐人是没有影响的,如果要满足两个四人家庭,那么座位2345要连续空着,6789要连续空着。如果上述条件不满足,也许能满足一个家庭,那么4567要连续空着。检查这几个位置是否连续空着。因为一开始记录已经被占的位置是通过把1左移若干位得到的,所以如果某个位置被reserve,这一位扇应该是1。所以当我们去检查比如2345这几个位置是否空着的时候,我们可以把map.get(row)背后的value直接和60,960,240做AND操作,如果结果为0则说明这几个位置是空着的。

    举个例子,以下的二进制表示座位号1到10的时候是从右往左看的,但是因为表示二进制的时候第一位只能从0开始,所以我们计算座位号的时候,实际是从0到9计算的。如果reserve记录的结果和如下的数字(对应digit上都是1)做AND == 0的话,说明相同位置上的digit都是0,因为0 & 1 == 0。

    60的二进制表示是 0000111100 - 2345这几个位子是空的

    960的二进制表示是 1111000000 - 6789这几个位子是空的

    240的二进制表示是 0011110000 - 4567这几个位子是空的

    最后注意return的东西,max自然是过程中我们计算的能为四人家庭reserve的座位数量,同时还需要再加上某些row没有任何预约的情形。

    时间O(n)

    空间O(n)

    Java实现

     1 class Solution {
     2     public int maxNumberOfFamilies(int n, int[][] reservedSeats) {
     3         HashMap<Integer, Integer> map = new HashMap<>();
     4         for (int[] seat : reservedSeats) {
     5             int row = seat[0];
     6             int col = seat[1];
     7             // create a bit vector of reserved seats
     8             map.put(row, map.getOrDefault(row, 0) | (1 << col));
     9         }
    10         int max = 0;
    11         for (int row : map.keySet()) {
    12             int reserved = map.get(row);
    13             int cnt = 0;
    14             if ((reserved & 60) == 0) {
    15                 cnt += 1; // check if seats 2,3,4,5 are available
    16             }
    17             if ((reserved & 960) == 0) {
    18                 cnt += 1; // check if seats 6,7,8,9 are available
    19             }
    20             if ((reserved & 240) == 0 && cnt == 0) {
    21                 cnt = 1; // check if seats 4,5,6,7 are available
    22             }
    23             max += cnt;
    24         }
    25         // map.size()是已经有预约的rows
    26         // n - map.size()是没有任何预约的rows
    27         return max + 2 * (n - map.size());
    28     }
    29 }

    LeetCode 题目总结 

  • 相关阅读:
    【codeforces 791D】 Bear and Tree Jumps
    【codeforces 791C】Bear and Different Names
    【codeforces 791B】Bear and Friendship Condition
    【codeforces 791A】Bear and Big Brother
    【t017】YL杯超级篮球赛
    Java Web整合开发(80) -- EJB & WebService
    搜索与排序
    T2821 天使之城 codevs
    T1155 金明的预算方案 codevs
    后缀表达式
  • 原文地址:https://www.cnblogs.com/cnoodle/p/14321529.html
Copyright © 2011-2022 走看看