是否有任何算法可以在飞行中分配连续3个座位,同时预订座位?

时间:2016-09-08 07:59:35

标签: algorithm

我想通过良好的算法在飞行中分配连续3个座位,同时预订座位。

基本上我想找不到可以预订的3个连续免费席位吗?

我试图通过贪婪的方式检查连续3个未预订的座位,然后计算总座位数来分配3个连续座位。

5 个答案:

答案 0 :(得分:2)

我对您的问题的解释:

你有N个座位。有K个席位(1个索引)已经预订。找出3个席位的连续段数,其中没有一个已被预订。

O(K log K)解决方案:

让预订的座位(按顺序)为B1,B2 ...... Bk。存储以下元素的排序列表:

[0,B1,B2,...,Bk,N+1]

对于每个免费席位(2个预订席位之间的所有席位都是免费的),拥有3个席位的连续段的方式的数量是max(0,S-2),其中S是该席位中的免费席位数。

例如,有10个座位,座位3和9被占用。

该列表将包含:[0,3,9,11]

第一部分将有3-0-1 = 2个免费席位。因此max(0,2-2)为0。

第二部分将有9-3-1 = 5个免费席位。因此max(0,5-2)是3。

第三个赛段将有11-9-1 = 1个免费席位。因此max(0,1-2)为0。

因此,正好有3种方法可以拥有3个席位的3个连续部分。

此处的复杂性为O(K log K),因为有K个元素需要在K log K时间内进行排序,而每个K+1段需要O(1)时间进行计算。如果N非常大(数十亿)而K更小(~100000),则更可行。

O(N)解决方案

如果全部免费,请检查每3个座位。如果K更大(数百万)并且N更小(当然仍然大于或等于K),这是可行的

答案 1 :(得分:2)

//n - number of rows, s- occupied seats
 `public int getAvailableSeats(int n, String s) {
    String str[] = s.split(" ");
    List<String> occupied = new ArrayList<>();
    int available = 0;

    occupied = Arrays.asList(str);

    for(int i = 1; i<= n ; i++) {

            if(!occupied.contains(i+"A") && !occupied.contains(i+"B") && !occupied.contains(i+"C")) {
                available++;
            }
            if(!(occupied.contains(i+"D") && occupied.contains(i+"G"))  && !(occupied.contains(i+"E") || occupied.contains(i+"F"))) {
                available++;
            }
            if(!occupied.contains(i+"H") && !occupied.contains(i+"J") && !occupied.contains(i+"K")) {
                available++;
            }
   }
    return available;
    }`

答案 2 :(得分:0)

来自@Benson Lin的 O(K log K)解决方案的Python实现。

def solution(N: int, S: str, n: int) -> int:
    """
    return option count
    """
    taken = [[] for _ in range(N)]
    for s in S.split(" "):
        row = int(s[:-1]) - 1
        if row > N:
            raise Exception("illegal reservation")

        taken[row].append(ord(s[-1]) - ord('A'))

    total_cnt = 0
    for row in taken:
        row.sort()
        row.append(ord('K') - ord('A') + 1)
        last = -1

        cnt = 0
        for idx in range(len(row)):
            free_seats = row[idx] - last - 1
            cnt += max(0, free_seats - (n - 1))
            last = row[idx]

        total_cnt += cnt

    return total_cnt

答案 3 :(得分:0)

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class Solution {

    public static void main(String[] args) {
        System.out.println("countFamilySeats" + familySeats(1, "1D 4C 5E"));
        
    }
    public static  int familySeats(int planeRows,String occupiedSeats){
            Map<Integer, String> seatMap = new HashMap<>();
            int countFamilySeats = 0;
        if (occupiedSeats == null || occupiedSeats.isEmpty()) {
            return planeRows * 3;
        }
          //for the Aisles : i have mentioned Z character
        for (int i = 1; i <= planeRows; i++) {
            String myData = new String("ABCZDEFGZHJK");
            seatMap.put(i, myData);
        }
        String[] occupiedSeatsArray = occupiedSeats.split(" ");
        
        System.out.println(seatMap.size());
        // int i=0;
        for (String occupied : occupiedSeatsArray) {
            char seatRow = occupied.charAt(0);
            char seatName = occupied.charAt(1);
            int row = Character.getNumericValue(seatRow);
            String seatNameCurrent = seatMap.get(row);

            String newSeatName = seatNameCurrent != null ? seatNameCurrent.replace(seatName, 'X') : null;
            System.out.println("Updating : " +newSeatName + " for row " + row);
            seatMap.put(row, newSeatName);
        }

        // AB?|DE?F|HJK
        for (Map.Entry<Integer, String> entry : seatMap.entrySet()) {
            
            String seatMapWithOccupiedData = entry.getValue();
            
            if (seatMapWithOccupiedData!=null && seatMapWithOccupiedData.contains("X")) {
                String[] tempSeatName = entry.getValue().split("X");
                for (String combinedSeats : tempSeatName) {
                    if (combinedSeats.length() <= 3) {
                        continue;
                    }
                    System.out.println("X is found : " + combinedSeats);
                    if (combinedSeats.length() >= 3 && !combinedSeats.contains("Z")) {
                        countFamilySeats++;
                    } else if (combinedSeats.length() >= 3 && combinedSeats.contains("Z")) {
                        String[] temp = combinedSeats.split("Z");
                        System.out.println(temp.length);
                        for (String t1 : temp) {
                            System.out.println("AISLE Separation " + t1);
                            if (t1.length() >= 3)
                                countFamilySeats++;
                        }
                    } else {
                        System.out.println("This portion is not suitable for family" + combinedSeats);
                    }

                }
            } else {
                countFamilySeats += 3;
            }

            System.out.println(" Till this row :"+entry.getKey()+"  family seats allowed :  " + countFamilySeats);
            
        }
        

    enter code here
        return countFamilySeats;
    }

}

答案 4 :(得分:0)

我在Codility中完成了类似的招聘测试任务。我是用位算术完成的。 一排座位的已占用座位图可以编码为位掩码,例如:0b1001000011,其中1表示已占用座位 然后填充所有已占用座位的哈希图(rowNum->该行的已占用座位图)

使用位按或对座位进行测试:测试已占用OR required_mask == required_mask, 其中所需的遮罩是连续放置的编码图案(例如:0001111000或001100000)。对于给定的N行,假设每行连续座位分配的选项数量有限(最大的A380飞机在一行中有10个座位,由两个小岛隔开),那么复杂度将为O(N),因此所有连续组合都可以编码为位掩码)