-
Notifications
You must be signed in to change notification settings - Fork 823
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Insert Delete GetRandom O(1) - Duplicates allowed: Accepted
- Loading branch information
1 parent
25dfc53
commit ec72949
Showing
2 changed files
with
116 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package design; | ||
import java.util.*; | ||
|
||
/** | ||
* Created by gouthamvidyapradhan on 14/04/2018. | ||
* Design a data structure that supports all following operations in average O(1) time. | ||
Note: Duplicate elements are allowed. | ||
insert(val): Inserts an item val to the collection. | ||
remove(val): Removes an item val from the collection if present. | ||
getRandom: Returns a random element from current collection of elements. The probability of each element being | ||
returned is linearly related to the number of same value the collection contains. | ||
Example: | ||
// Init an empty collection. | ||
RandomizedCollection collection = new RandomizedCollection(); | ||
// Inserts 1 to the collection. Returns true as the collection did not contain 1. | ||
collection.insert(1); | ||
// Inserts another 1 to the collection. Returns false as the collection contained 1. Collection now contains [1,1]. | ||
collection.insert(1); | ||
// Inserts 2 to the collection, returns true. Collection now contains [1,1,2]. | ||
collection.insert(2); | ||
// getRandom should return 1 with the probability 2/3, and returns 2 with the probability 1/3. | ||
collection.getRandom(); | ||
// Removes 1 from the collection, returns true. Collection now contains [1,2]. | ||
collection.remove(1); | ||
// getRandom should return 1 and 2 both equally likely. | ||
collection.getRandom(); | ||
Solution O(1) for each operation. Maintain a hashmap of value -> {set of indices}; Set of indices are indices of array | ||
containing the value. | ||
Insert: Insert a element in end of array and add the index of array as the set of values in hashmap. | ||
Remove: If the hashmap contains value remove a random element from the set and replace the element at that index | ||
with the last element from array and remove the last element from the array. Since we are removing the last | ||
element from array this operation requires only O(1) time | ||
getRandom(): Generate a random number between 0 and size of array and return the element at that position. | ||
*/ | ||
public class RandomizedCollection { | ||
|
||
private Map<Integer, Set<Integer>> map; | ||
private List<Integer> list; | ||
|
||
/** Initialize your data structure here. */ | ||
public RandomizedCollection() { | ||
map = new HashMap<>(); | ||
list = new ArrayList<>(); | ||
} | ||
|
||
/** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ | ||
public boolean insert(int val) { | ||
boolean status = map.containsKey(val); | ||
Set<Integer> set = map.get(val); | ||
if(set == null){ | ||
set = new HashSet<>(); | ||
map.put(val, set); | ||
} | ||
list.add(val); | ||
set.add(list.size() - 1); | ||
return !status; | ||
} | ||
|
||
/** Removes a value from the collection. Returns true if the collection contained the specified element. */ | ||
public boolean remove(int val) { | ||
if(map.containsKey(val)){ | ||
Set<Integer> set = map.get(val); | ||
int valIndex = set.iterator().next(); | ||
set.remove(valIndex); | ||
if(set.isEmpty()){ | ||
map.remove(val); | ||
} | ||
if(valIndex == list.size() - 1){ //if this is the last index then simply remove it | ||
list.remove(list.size() - 1); | ||
} else{ | ||
int lastEle = list.get(list.size() - 1); | ||
map.get(lastEle).remove(list.size() - 1); | ||
map.get(lastEle).add(valIndex); | ||
list.set(valIndex, lastEle); | ||
list.remove(list.size() - 1); | ||
} | ||
return true; | ||
} else return false; | ||
} | ||
|
||
/** Get a random element from the collection. */ | ||
public int getRandom() { | ||
Random random = new Random(); | ||
return list.get(random.nextInt(list.size())); | ||
} | ||
|
||
/** | ||
* Main method | ||
* @param args | ||
* @throws Exception | ||
*/ | ||
public static void main(String[] args) throws Exception{ | ||
RandomizedCollection collection = new RandomizedCollection(); | ||
System.out.println(collection.insert(1)); | ||
System.out.println(collection.insert(1)); | ||
System.out.println(collection.insert(2)); | ||
System.out.println(collection.getRandom()); | ||
System.out.println(collection.remove(2)); | ||
System.out.println(collection.getRandom()); | ||
System.out.println(collection.remove(1)); | ||
System.out.println(collection.getRandom()); | ||
System.out.println(collection.remove(1)); | ||
} | ||
|
||
|
||
} |