在设计和时间复杂度方面,您当然可以做得比多维 ArrayList 更好。
从设计的角度来看,您有三个包含类 - Room、House 和 Base。 (也可以是Soldier,尽管出于我们的目的,Soldier 不需要任何额外信息。)
public class Soldier{}
首先,Room 相当简单。它必须包含Soldiers 并知道它还剩下多少个开放房间
public class Room {
private int totalBeds;
public final int priority;
private ArrayList<Soldier> soldiers;
public Room(int totalBeds, int priority) {
this.totalBeds = totalBeds;
this.priority = priority;
soldiers = new ArrayList<>();
}
public boolean add(Solider s) {
if(soldiers.size() >= totalBeds) {
return false;
}
return soldiers.add(s);
}
public int getRemainingBeds() {
return totalBeds - soldiers.size();
}
public boolean isFull() {
return totalBeds <= soldiers.size();
}
}
从那里,我们需要一个House 类。这是Rooms 的优先级队列,必须能够根据其优先级将士兵添加到房间。
public class House {
private final String name;
private PriorityQueue<Room> rooms;
public House(String name, Room... rooms) {
this.name = name;
this.rooms = new PriorityQueue<>(new Comparator<Room>() {
public int compare(Room a, Room b) {
//Always prioritize an open room to a full one
if(a.isFull() && b.isFull()) {
return 0;
} else if (a.isFull()) {
return 1;
} else if (b.isFull()) {
return -1;
} else {
//Now try to get the room with the most available rooms
int bedDiff = b.getRemainingBeds() - a.getRemainingBeds();
if(bedDiff != 0) {
return bedDiff;
}
return a.priority - b.priority;
}
}
});
for(Room r : rooms) {
this.rooms.add(r)
}
}
public boolean add(Soldier s) {
Room r = rooms.poll();
boolean ok = r.add(s);
rooms.add(r);
return ok;
}
public String getName() {
return name;
}
}
最后,Base 类应该使用Map<String, House> 来通过名称快速定位房子
public class Base {
private Map<String, House> houses;
public Base(House... houses) {
houses = new HashMap<>();
for(House h : houses) {
houses.put(h.getName(), h);
}
}
public boolean add(String houseName, Soldier s) {
return houses.get(houseName).add(s);
}
}
将士兵添加到基地的全时复杂度:
- Finding the correct House: O(1)
- Adding to the House:
- Poll: O(log(#rooms in house))
- Add to room: O(1)
- Add: O(log(#rooms in house))