solution.md 6.4 KB
Newer Older
每日一练社区's avatar
每日一练社区 已提交
1
# O(1) 时间插入、删除和获取随机元素 - 允许重复
F
fix bug  
feilong 已提交
2

每日一练社区's avatar
每日一练社区 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
<p>设计一个支持在<em>平均&nbsp;</em>时间复杂度&nbsp;<strong>O(1)&nbsp;</strong><strong>&nbsp;</strong>执行以下操作的数据结构。</p>

<p><strong>注意: 允许出现重复元素。</strong></p>

<ol>
	<li><code>insert(val)</code>:向集合中插入元素 val。</li>
	<li><code>remove(val)</code>:当 val 存在时,从集合中移除一个 val。</li>
	<li><code>getRandom</code>:从现有集合中随机获取一个元素。每个元素被返回的概率应该与其在集合中的数量呈线性相关。</li>
</ol>

<p><strong>示例:</strong></p>

<pre>// 初始化一个空的集合。
RandomizedCollection collection = new RandomizedCollection();

// 向集合中插入 1 。返回 true 表示集合不包含 1 。
collection.insert(1);

// 向集合中插入另一个 1 。返回 false 表示集合包含 1 。集合现在包含 [1,1] 。
collection.insert(1);

// 向集合中插入 2 ,返回 true 。集合现在包含 [1,1,2] 。
collection.insert(2);

// getRandom 应当有 2/3 的概率返回 1 ,1/3 的概率返回 2 。
collection.getRandom();

// 从集合中删除 1 ,返回 true 。集合现在包含 [1,2] 。
collection.remove(1);

// getRandom 应有相同概率返回 1 和 2 。
collection.getRandom();
</pre>

每日一练社区's avatar
每日一练社区 已提交
37
<p>以下<span style="color:red">错误</span>的选项是?</p>
F
fix bug  
feilong 已提交
38

每日一练社区's avatar
每日一练社区 已提交
39
## aop
F
fix bug  
feilong 已提交
40

每日一练社区's avatar
每日一练社区 已提交
41
### before
F
fix bug  
feilong 已提交
42

每日一练社区's avatar
每日一练社区 已提交
43
```cpp
每日一练社区's avatar
每日一练社区 已提交
44 45 46
#include <bits/stdc++.h>
using namespace std;
```
每日一练社区's avatar
每日一练社区 已提交
47

每日一练社区's avatar
每日一练社区 已提交
48
### after
F
fix bug  
feilong 已提交
49

每日一练社区's avatar
每日一练社区 已提交
50
```cpp
每日一练社区's avatar
每日一练社区 已提交
51 52 53 54

```

## 答案
F
fix bug  
feilong 已提交
55

每日一练社区's avatar
每日一练社区 已提交
56
```cpp
每日一练社区's avatar
每日一练社区 已提交
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
class RandomizedCollection
{
public:
    /** Initialize your data structure here. */
    RandomizedCollection()
    {
        this->num = 0;
    }

    /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
    bool insert(int val)
    {
        this->num++;
        bool res;
        if (this->M.find(val) == this->M.end() || this->M[val] == 0)
        {
            this->M[val] = 1;
            res = true;
        }
        else
        {
            this->M[val]++;
            res = false;
        }
        return res;
    }

    /** Removes a value from the collection. Returns true if the collection contained the specified element. */
    bool remove(int val)
    {
        if (this->M.find(val) == this->M.end() || this->M[val] == 0)
        {
            return false;
        }
        else
        {
            M[val]--;
            this->num--;
            return true;
        }
    }

    /** Get a random element from the collection. */
    int getRandom()
    {
        if (this->num > 0)
        {
            srand((unsigned)time(NULL));
            int randomValue = rand() % (this->num) + 1;
            for (auto it : M)
            {
                randomValue -= it.second;
                if (randomValue <= 0)
                    return it.first;
            }
        }
        return 0;
    }

private:
    unordered_map<int, int> M;
    int num;
};
```
## 选项

F
fix bug  
feilong 已提交
123

每日一练社区's avatar
每日一练社区 已提交
124
### A
F
fix bug  
feilong 已提交
125

每日一练社区's avatar
每日一练社区 已提交
126
```cpp
每日一练社区's avatar
每日一练社区 已提交
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
class RandomizedSet
{
public:
    vector<int> nums;
    unordered_map<int, int> numIndex;
    int size;
    /** Initialize your data structure here. */
    RandomizedSet()
    {
        size = 0;
    }

    /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
    bool insert(int val)
    {
        if (numIndex.count(val) == 1)
            return false;
        nums.push_back(val);
        numIndex[val] = size;
        size++;
        return true;
    }

    /** Removes a value from the set. Returns true if the set contained the specified element. */
    bool remove(int val)
    {
        if (numIndex.count(val) == 0)
            return false;
        int last = nums.back();
        nums[numIndex[val]] = last;
        numIndex[last] = numIndex[val];
        nums.pop_back();
        numIndex.erase(val);
        size--;
        return true;
    }

    /** Get a random element from the set. */
    int getRandom()
    {
        return nums[random() % size];
    }
};
```

### B
F
fix bug  
feilong 已提交
173

每日一练社区's avatar
每日一练社区 已提交
174
```cpp
每日一练社区's avatar
每日一练社区 已提交
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
class RandomizedCollection
{
public:
    unordered_map<int, unordered_set<int>> idx;
    vector<int> nums;

    /** Initialize your data structure here. */
    RandomizedCollection()
    {
    }

    /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
    bool insert(int val)
    {
        nums.push_back(val);
        idx[val].insert(nums.size() - 1);
        return idx[val].size() == 1;
    }

    /** Removes a value from the collection. Returns true if the collection contained the specified element. */
    bool remove(int val)
    {
        if (idx.find(val) == idx.end())
        {
            return false;
        }
        int i = *(idx[val].begin());
        nums[i] = nums.back();
        idx[val].erase(i);
        idx[nums[i]].erase(nums.size() - 1);
        if (i < nums.size() - 1)
        {
            idx[nums[i]].insert(i);
        }
        if (idx[val].size() == 0)
        {
            idx.erase(val);
        }
        nums.pop_back();
        return true;
    }

    /** Get a random element from the collection. */
    int getRandom()
    {
        return nums[rand() % nums.size()];
    }
};
```

### C
F
fix bug  
feilong 已提交
226

每日一练社区's avatar
每日一练社区 已提交
227
```cpp
每日一练社区's avatar
每日一练社区 已提交
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
class RandomizedCollection
{
public:
    vector<int> nums;
    unordered_map<int, unordered_set<int>> numsIndex;
    int size;
    /** Initialize your data structure here. */
    RandomizedCollection()
    {
        size = 0;
    }

    /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
    bool insert(int val)
    {
        nums.push_back(val);
        numsIndex[val].insert(size);
        size++;
        return numsIndex[val].size() == 1;
    }

    /** Removes a value from the collection. Returns true if the collection contained the specified element. */
    bool remove(int val)
    {
        if (numsIndex.count(val) == 0)
            return false;
        int last = nums.back();
        int id = size - 1;
        if (last != val)
        {
            id = *(numsIndex[val].begin());
            numsIndex[last].erase(size - 1);
            numsIndex[last].insert(id);
            nums[id] = last;
        }
        nums.pop_back();
        size--;
        numsIndex[val].erase(id);
        if (numsIndex[val].empty())
            numsIndex.erase(val);
        return true;
    }

    /** Get a random element from the collection. */
    int getRandom()
    {
        return nums[random() % size];
    }
};
```