我想通过良好的算法在飞行中分配连续3个座位,同时预订座位。
基本上我想找不到可以预订的3个连续免费席位吗?
我试图通过贪婪的方式检查连续3个未预订的座位,然后计算总座位数来分配3个连续座位。
答案 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),因此所有连续组合都可以编码为位掩码)