1+ package com .leetcode .design ;
2+
3+ import java .util .*;
4+
5+ import static org .junit .jupiter .api .Assertions .*;
6+
7+ /**
8+ * Level: Medium
9+ * Link: https://leetcode.com/problems/insert-delete-getrandom-o1/
10+ * Description:
11+ * Design a data structure that supports all following operations in average O(1) time.
12+ *
13+ * insert(val): Inserts an item val to the set if not already present.
14+ * remove(val): Removes an item val from the set if present.
15+ * getRandom: Returns a random element from current set of elements. Each element must have the same probability of
16+ * being returned.
17+ *
18+ * Example:
19+ *
20+ * // Init an empty set.
21+ * RandomizedSet randomSet = new RandomizedSet();
22+ *
23+ * // Inserts 1 to the set. Returns true as 1 was inserted successfully.
24+ * randomSet.insert(1);
25+ *
26+ * // Returns false as 2 does not exist in the set.
27+ * randomSet.remove(2);
28+ *
29+ * // Inserts 2 to the set, returns true. Set now contains [1,2].
30+ * randomSet.insert(2);
31+ *
32+ * // getRandom should return either 1 or 2 randomly.
33+ * randomSet.getRandom();
34+ *
35+ * // Removes 1 from the set, returns true. Set now contains [2].
36+ * randomSet.remove(1);
37+ *
38+ * // 2 was already in the set, so return false.
39+ * randomSet.insert(2);
40+ *
41+ * // Since 2 is the only number in the set, getRandom always return 2.
42+ * randomSet.getRandom();
43+ *
44+ * Runtime: <a href="https://leetcode.com/submissions/detail/250682053/>52 ms</a>.
45+ *
46+ * @author rampatra
47+ * @since 2019-08-11
48+ */
49+ public class InsertDeleteGetRandom {
50+ // store the val and its index (from the array list to make the remove O(1))
51+ Map <Integer , Integer > valuesToIndexMap ;
52+ List <Integer > values ;
53+ Random random ;
54+
55+ InsertDeleteGetRandom () {
56+ valuesToIndexMap = new HashMap <>();
57+ values = new ArrayList <>();
58+ random = new Random ();
59+ }
60+
61+ boolean insert (int val ) {
62+ if (valuesToIndexMap .containsKey (val )) {
63+ return false ;
64+ }
65+
66+ valuesToIndexMap .put (val , values .size ());
67+ values .add (val );
68+ return true ;
69+ }
70+
71+ boolean remove (int val ) {
72+ Integer index = valuesToIndexMap .get (val );
73+
74+ if (index == null ) {
75+ return false ;
76+ }
77+
78+ if (index != values .size () - 1 ) {
79+ int lastValue = values .get (values .size () - 1 );
80+ values .set (index , lastValue ); // replace the value with the last value
81+ valuesToIndexMap .put (lastValue , index ); // update index in the map
82+ }
83+ values .remove (values .size () - 1 );
84+ return valuesToIndexMap .remove (val , index );
85+ }
86+
87+ int getRandom () {
88+ return values .get (random .nextInt (values .size ()));
89+ }
90+
91+ public static void main (String [] args ) {
92+ InsertDeleteGetRandom randomizedSet = new InsertDeleteGetRandom ();
93+ assertTrue (randomizedSet .insert (2 ));
94+ assertTrue (randomizedSet .insert (-1 ));
95+ assertFalse (randomizedSet .remove (-10 ));
96+ assertTrue (randomizedSet .remove (-1 ));
97+ assertEquals (2 , randomizedSet .getRandom ());
98+ assertTrue (randomizedSet .remove (2 ));
99+ assertFalse (randomizedSet .remove (-2 ));
100+ assertFalse (randomizedSet .remove (-20 ));
101+ assertFalse (randomizedSet .remove (-30 ));
102+ assertFalse (randomizedSet .remove (2 ));
103+ assertFalse (randomizedSet .remove (1 ));
104+ assertFalse (randomizedSet .remove (0 ));
105+ }
106+ }
0 commit comments