程序员面试金典-面试题 03.06. 动物收容所
题目:
动物收容所。有家动物收容所只收容狗与猫,且严格遵守“先进先出”的原则。在收养该收容所的动物时,收养人只能收养所有动物中“最老”(由其进入收容所的时间长短而定)的动物,或者可以挑选猫或狗(同时必须收养此类动物中“最老”的)。换言之,收养人不能自由挑选想收养的对象。请创建适用于这个系统的数据结构,实现各种操作方法,比如enqueue、dequeueAny、dequeueDog和dequeueCat。允许使用Java内置的LinkedList数据结构。
enqueue方法有一个animal参数,animal[0]代表动物编号,animal[1]代表动物种类,其中 0 代表猫,1 代表狗。
dequeue*方法返回一个列表[动物编号, 动物种类],若没有可以收养的动物,则返回[-1,-1]。
示例1:
输入:
["AnimalShelf", "enqueue", "enqueue", "dequeueCat", "dequeueDog", "dequeueAny"]
[[], [[0, 0]], [[1, 0]], [], [], []]
输出:
[null,null,null,[0,0],[-1,-1],[1,0]]
示例2:
输入:
["AnimalShelf", "enqueue", "enqueue", "enqueue", "dequeueDog", "dequeueCat", "dequeueAny"]
[[], [[0, 0]], [[1, 0]], [[2, 1]], [], [], []]
输出:
[null,null,null,null,[2,1],[0,0],[1,0]]
说明:
收纳所的最大容量为20000
分析:
可以利用两个list,也可以使用1个list。两个list的好处在于在收养猫狗时可以直接返回最老的猫和狗,也就是头部的元素。
一个list的话就按收容的顺序,当领养猫或狗时,就从头找到第一只猫或者狗,然后删除即可。
不过感觉还是两个list比较好,存入的时候把序号也存入,当任意收养的时候,比较两个list头部的大小,返回小的即可。
不过两个方法差别不大,时间都是100ms以内,不过个人更喜欢第二种。
程序:
//95 ms by two list class AnimalShelf { public AnimalShelf() { list = new LinkedList<>(); } public void enqueue(int[] animal) { list.add(animal); } public int[] dequeueAny() { if(list.isEmpty()) return new int[]{-1, -1}; return list.removeFirst(); } public int[] dequeueDog() { int[] res = new int[]{-1, -1}; for(int i = 0; i < list.size(); ++i){ if(list.get(i)[1] == 1){ res[0] = list.get(i)[0]; res[1] = 1; list.remove(i); break; } } return res; } public int[] dequeueCat() { int[] res = new int[]{-1, -1}; for(int i = 0; i < list.size(); ++i){ if(list.get(i)[1] == 0){ res[0] = list.get(i)[0]; res[1] = 0; list.remove(i); break; } } return res; } private LinkedList<int[]> list; } /** * Your AnimalShelf object will be instantiated and called as such: * AnimalShelf obj = new AnimalShelf(); * obj.enqueue(animal); * int[] param_2 = obj.dequeueAny(); * int[] param_3 = obj.dequeueDog(); * int[] param_4 = obj.dequeueCat(); */
//97 ms by one list class AnimalShelf { public AnimalShelf() { listDog = new LinkedList<>(); listCat = new LinkedList<>(); } public void enqueue(int[] animal) { if(animal[1] == 0) listCat.add(animal[0]); else listDog.add(animal[0]); } public int[] dequeueAny() { if(listCat.isEmpty() && listDog.isEmpty()) return new int[]{-1, -1}; if(listCat.isEmpty()) return new int[]{listDog.removeFirst(), 1}; else if(listDog.isEmpty()) return new int[]{listCat.removeFirst(), 0}; else{ return listCat.getFirst() < listDog.getFirst() ? new int[]{listCat.removeFirst(), 0} : new int[]{listDog.removeFirst(), 1}; } } public int[] dequeueDog() { return listDog.isEmpty() ? new int[]{-1, -1} : new int[]{listDog.removeFirst(), 1}; } public int[] dequeueCat() { return listCat.isEmpty() ? new int[]{-1, -1} : new int[]{listCat.removeFirst(), 0}; } private LinkedList<Integer> listDog; private LinkedList<Integer> listCat; } /** * Your AnimalShelf object will be instantiated and called as such: * AnimalShelf obj = new AnimalShelf(); * obj.enqueue(animal); * int[] param_2 = obj.dequeueAny(); * int[] param_3 = obj.dequeueDog(); * int[] param_4 = obj.dequeueCat(); */