【问题标题】:Hotel Bookings Bookings Possible酒店预订 可能预订
【发布时间】:2016-09-23 12:37:24
【问题描述】:

我已经实现了一个简短的算法来判断是否所有酒店预订都是可能的。问题和this很像,不过我尝试过实现自己的逻辑。

(很抱歉这么长的解释)

在我的算法中

  1. int K= 可用房间数
  2. ArrayList<Integer>到达=客人到达时间
  3. ArrayList<Integer> leave = 客人出发时间
  4. intaving_guest = 下一位客人
  5. ArrayList<ArrayList<Integer>>arrange = 房间分配

例如

  • 到达 = [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;
    }

【问题讨论】:

  • 我不会确切地找出问题所在,但我可以发现在arrange 中仅跟踪出发 日期的问题。假设departarrive中的第一个条目是5,10,第二个条目是2,3。你的算法会做什么?这是正确的吗?尝试按到达和离开时间对客人进行预分类,看看会发生什么。

标签: java algorithm arraylist


【解决方案1】:

如果我们将问题概括为以下内容:给定区间 (a_i, b_i),找到最大数量的线段交点。

算法如下:

  1. 创建另一个数组对:(a_i, false) 或 (b_i, true),其中第一个 一个值表示该值,第二个是布尔标志,如果它是开始或 段的结尾。
  2. 按第一个坐标对其进行排序,如果出现平局,请确保末端对先行。
  3. 遍历结果数组并保持本地房间数。如果是段的开头,则增加房间数,如果是结尾,则减少房间数。

这是算法的一个实现:

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;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    • 1970-01-01
    • 1970-01-01
    • 2012-03-27
    • 1970-01-01
    相关资源
    最近更新 更多