Skip to content

Instantly share code, notes, and snippets.

@mptap
Last active October 14, 2018 16:43
Show Gist options
  • Save mptap/2e57c484d4c5b35bbbd416934d1d385a to your computer and use it in GitHub Desktop.
Save mptap/2e57c484d4c5b35bbbd416934d1d385a to your computer and use it in GitHub Desktop.
Implement a set-like data structure that supports Insert, Remove, and GetRandomElement efficiently. Example: If you insert the elements 1, 3, 6, 8 and remove 6, the structure should contain [1, 3, 8]. Now, GetRandom should return one of 1, 3 or 8 with equal probability
public class SetLikeDS {
private List<Integer> list;
private Map<Integer, Integer> map;
public SetLikeDS() {
list = new ArrayList<>();
map = new HashMap<>();
}
public void insert(int num) {
if (!map.containsKey(num)) { //insert if not present only, set-like
list.add(num); //O(1) as adding at end
int index = list.size()-1;
map.put(num, index); //O(1)
}
}
public void remove(int num) {
if (map.containsKey(num)) { //can remove if present only
int index = map.get(num); //O(1)
int last = list.get(list.size()-1); //O(1) as accessing at known index
list.set(index, last); //O(1) as replacing at and from known indices
list.remove(list.size()-1); //O(1) as removing last element
map.remove(num); //O(1)
map.put(last, index); //update index
}
}
public int getRandom() {
int rand = ThreadLocalRandom.current().nextInt(0, list.size()); //0 and list.size()-1 should both be inclusive
return list.get(rand); //O(1) as accessing at known index
}
}
@kcochibili
Copy link

For the remove(), I feel your implementation is incomplete. I modified your code to loop trough all items after the the item that is to be deleted, and update their indexes in the HashMap

	public void remove(int num) {
		if (map.containsKey(num)) { //can remove if present only					
      		       int index = map.get(num); //O(1)	
                       for( int i = index + 1; i < list.size(); i++){ // int i = index + 1  // I added one so as to not update the index of the item that is about to be deleted
                             int itemKey = list.get(i);
                             int newIndex =  i -1;
                             map.set(itemKey, newIndex);
                       }
                       list.remove(i);
                       map.remove();
                      
		}
	}

What do you think?

@rotunba
Copy link

rotunba commented Oct 14, 2018

Your loop helps move all the elements after the removed element but the requirement doesn't state that all the elements should be moved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment