Approach 1: You can use TreeMap
and iterate through its keys, and if there is a gap between two keys, you can insert your element in this gap. Addition will work in O(currentKeysCount)
worst-case, deletion will work in O(log(currentKeysCount))
.
private TreeMap<Integer, Track> tracks;
public Register() {
this.trains = new TreeMap<>();
}
public void addTrack(Track track) {
int id = 1;
for (int key : this.trains.keySet) {
if (key > id) break;
id = key + 1;
}
this.tracks.put(id, track);
}
public void removeTrack(int id) {
if (tracks.containsKey(id)) {
this.tracks.remove(id);
} else {
Terminal.printError("track with ID " + track.getId() + " doesn't exist.");
}
}
Approach 2: You can create a PriorityQueue
that will store deleted keys. Addition and deletion will work in O(log(currentKeysCount) + log(deletedKeysCount))
.
private Map<Integer, Track> tracks;
private PriorityQueue<Integer> deletedKeys;
private int nextKey;
public Register() {
this.trains = new HashMap<>();
this.deletedKeys = new PriorityQueue<>();
this.nextKey = 0;
}
public void addTrack(Track track) {
int id = nextKey;
if (!deletedKeys.isEmpty()) id = deletedKeys.poll();
this.tracks.put(id, track);
}
public void removeTrack(int id) {
if (tracks.containsKey(id)) {
this.tracks.remove(id);
this.deletedKeys.add(id);
} else {
Terminal.printError("track with ID " + track.getId() + " doesn't exist.");
}
}
Approach 3: It may be much easier to ignore missing keys and just increase nextKey
counter on every addition (you can even use long
instead of int
). Unless you add a new key more often than once per millisecond, your program won't fail earlier than all code that uses System.currentTimeMillis()
(and it will fail in more than 292 million years). Addition and deletion will work in O(log(currentKeysCount))