Leetcode 381: Insert Delete GetRandom O(1) - Duplicates allowed

Design a data structure that supports all following operations in average O(1) time.

Note: Duplicate elements are allowed.

 

  1. insert(val): Inserts an item val to the collection.
  2. remove(val): Removes an item val from the collection if present.
  3. 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();

 

 

 

 1 public class RandomizedCollection {
 2     private Dictionary<int, IList<int>> dict = new Dictionary<int, IList<int>>();
 3     
 4     // first parameter is the key, second parameter is index in above dict's value (list)
 5     private IList<Tuple<int, int>> list = new List<Tuple<int, int>>(1000); 
 6     
 7     private Random random = new Random();
 8     
 9     /** Initialize your data structure here. */
10     public RandomizedCollection() {
11         
12     }
13     
14     /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
15     public bool Insert(int val) {
16         if (!dict.ContainsKey(val))
17         {
18             dict[val] = new List<int>();
19             dict[val].Add(list.Count);
20             list.Add(new Tuple<int, int>(val, 0));
21             
22             return true;
23         }
24         else
25         {
26             dict[val].Add(list.Count);
27             list.Add(new Tuple<int, int>(val, dict[val].Count - 1));
28             
29             return false;
30         }
31     }
32     
33     /** Removes a value from the collection. Returns true if the collection contained the specified element. */
34     public bool Remove(int val) {
35         if (dict.ContainsKey(val) && dict[val].Count > 0)
36         {
37             int toRemoveIndex = dict[val][dict[val].Count - 1];           
38             var last = list[list.Count - 1];
39             
40             // swap last element with the element to remove
41             this.list[toRemoveIndex] = last;
42             dict[last.Item1][last.Item2] = toRemoveIndex;
43             list.RemoveAt(list.Count - 1);
44             
45             // remove val from dict
46             dict[val].RemoveAt(dict[val].Count - 1);          
47             if (dict[val].Count == 0)
48             {
49                 dict.Remove(val);
50             }
51             
52             return true;
53         }
54         else
55         {
56             return false;
57         }
58     }
59     
60     /** Get a random element from the collection. */
61     public int GetRandom() {
62         if (list.Count == 0)
63         {
64             throw new Exception();
65         }
66         else
67         {
68             return this.list[random.Next() % list.Count].Item1;
69         }
70     }
71 }
72 
73 /**
74  * Your RandomizedCollection object will be instantiated and called as such:
75  * RandomizedCollection obj = new RandomizedCollection();
76  * bool param_1 = obj.Insert(val);
77  * bool param_2 = obj.Remove(val);
78  * int param_3 = obj.GetRandom();
79  */

 

posted @ 2018-01-02 03:49  逸朵  阅读(142)  评论(0)    收藏  举报