我已经实现了一个简短的算法来判断是否所有的酒店预订都是可能的这个问题与this非常相似,但我尝试实现自己的逻辑。
(很抱歉这么长时间的解释)
在我的算法中int
k=可用房间数ArrayList<Integer>
到达=客人到达时间ArrayList<Integer>
出发=客人出发时间int
到达客人=下一位客人ArrayList<ArrayList<Integer>>
排列=房间分配
例如
到达时间=[1,3,5]
出发=[2,6,8]和
K=1
现在在我们开始迭代之前,ArrayList<ArrayList<Integer>> arrange
将是[[2]]
因为最初所有房间都是可用的,int arriving_guest = 1
作为第一个客人被容纳,它将指向下一个客人
现在进行第一次迭代,客人的到达时间是3,出发时间是6
检查第一个房间是否有空
因为第一位客人的出发时间是2点,所以他的房间可以给第二位客人,所以arrange
将变成[[2,6]]
增量arriving_guest
指向下一个来宾
现在进行第二次迭代,客人的到达时间是5,出发时间是8
检查第一个房间是否有空
因为第二位客人的出发时间是6,所以他的房间不能给第三位客人,所以应该为第三位客人分配一个新房间,并且arrange
将变为[[2,6],[8]]
增量arriving_guest
指向下一个来宾
在算法的末尾
需要的房间数=arrange.size()
=2
可用客房数=K
=1
所以它将返回false
值
如果我对下面的测试用例应用我的算法,它将失败
到达时间:[14,29,0,35,34,15,17,7,28,13,40,28,11,40]
出发:[51,77,37,63,76,25,57,23,40,32,63,41,21,68]
K:9分
我的算法是
private static boolean bookingsPossible(ArrayList<Integer> arrive, ArrayList<Integer> depart, int K) {
// TODO Auto-generated method stub
int arriving_guest = 1;
ArrayList<ArrayList<Integer>> arrange = new ArrayList<ArrayList<Integer>>();
arrange.add(new ArrayList<Integer>(){{
add(depart.get(0));
}});
for(int i=0;i<depart.size();i++)
{
int temp = 0;
System.out.println("i is "+i);
while(temp <= i)
{
System.out.println("arriving guest "+arriving_guest);
if(arriving_guest < arrive.size() && arriving_guest < depart.size())
{
System.out.println("i is in if "+i);
if(temp <= (arrange.size() -1))
{
System.out.println("Temp is "+temp);
int vacatetime = arrange.get(temp).get(arrange.get(temp).size() - 1);
System.out.println("Vacate Time "+vacatetime+" Arrival Time "+arrive.get(arriving_guest));
if(vacatetime <= arrive.get(arriving_guest))
{
arrange.get(temp).add(depart.get(arriving_guest));
arriving_guest++;
System.out.println("Arrangement made "+arrange.toString());
break;
}
}
else
{
System.out.println("Adding room");
ArrayList<Integer> p = new ArrayList<Integer>();
p.add(depart.get(arriving_guest));
arrange.add(p);
System.out.println("Arrangement made "+arrange.toString());
arriving_guest++; break;
}
}
else
{
break;
}
temp++;
}
}
System.out.println("Rooms needed "+arrange.size());
System.out.println("Final Arrangement made "+arrange.toString());
return arrange.size() <= K ? true : false;
}
最佳答案
如果我们推广这个问题,它会变成如下:给定的间隔(AAI,BI I),找到最大数量的段交叉点。
算法如下:
制作另一个成对数组:(a_i,false)或(b_i,true),首先
值指示值,如果是开始或
线段的末端。
按第一个坐标排序,在打领带的情况下,请确保先打尾对。
遍历结果数组并保持本地房间计数。如果它是段的开始,增加一个房间数如果它是结束-减少。
下面是算法的实现:
public class HotelBooking {
private static class Pair implements Comparable<Pair>{
final int x;
final boolean isEnd;
public Pair(int x, boolean isEnd) {
this.x = x;
this.isEnd = isEnd;
}
@Override
public int compareTo(Pair o) {
int cmp = this.x - o.x;
//in case of tie be sure that end pair comes first
return cmp == 0 ? isEnd ? -1 : 1 : cmp;
}
}
public boolean hotel(ArrayList<Integer> arrive, ArrayList<Integer> depart, int K) {
if(arrive.size() == 0 || K == 0) return false; //base case
else if(arrive.size() == 1 && K > 1) return false; //base case
else {
int n = depart.size();
List<Pair> intervals = new ArrayList<>();
for (int i = 0; i < n; i++) {
intervals.add(new Pair(arrive.get(i), false));
intervals.add(new Pair(depart.get(i), true));
}
Collections.sort(intervals);
int count = 0; //
int maxRooms = 0;
for (int i = 0; i < intervals.size(); i++) {
Pair pair = intervals.get(i);
count += pair.isEnd ? -1 : 1;
maxRooms = Math.max(maxRooms, count);
}
return maxRooms > K ? false : true;
}
}
}