【数组】Leetcode编程题解:381. Insert Delete GetRandom O(1)
来源:互联网 发布:淘宝当当旗舰店 编辑:程序博客网 时间:2024/06/07 03:32
题目: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.样例:// 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();参考了网上的思路自己利用哈希表实现了一遍,但是因为存储数字下标使用的是vector向量,出现了越界的情况。以下为网上转载的正确解法:
这题是之前那道Insert Delete GetRandom O(1)的拓展,与其不同的是,之前那道题不能有重复数字,而这道题可以有,那么就不能像之前那道题那样建立每个数字和其坐标的映射了,但是我们可以建立数字和其所有出现位置的集合之间的映射,虽然写法略有不同,但是思路和之前那题完全一样,都是将数组最后一个位置的元素和要删除的元素交换位置,然后删掉最后一个位置上的元素。对于insert函数,我们将要插入的数字在nums中的位置加入m[val]数组的末尾,然后在数组nums末尾加入val,我们判断是否有重复只要看m[val]数组只有刚加的val一个值还是有多个值。remove函数是这题的难点,我们首先看哈希表中有没有val,没有的话直接返回false。然后我们取出nums的尾元素,把尾元素哈希表中的位置数组中的最后一个位置更新为m[val]的尾元素,这样我们就可以删掉m[val]的尾元素了,如果m[val]只有一个元素,那么我们把这个映射直接删除。然后我们将nums数组中的尾元素删除,并把尾元素赋给val所在的位置,注意我们在建立哈希表的映射的时候需要用堆而不是普通的vector数组,因为我们每次remove操作后都会移除nums数组的尾元素,如果我们用vector来保存数字的坐标,而且只移出末尾数字的话,有可能出现前面的坐标大小超过了此时nums的大小的情况,就会出错,所以我们用优先队列对所有的相同数字的坐标进行自动排序,每次把最大位置的坐标移出即可,参见代码如下:
class RandomizedCollection {public: /** 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) { m[val].push(nums.size()); nums.push_back(val); return m[val].size() == 1; } /** Removes a value from the collection. Returns true if the collection contained the specified element. */ bool remove(int val) { if (m[val].empty()) return false; int idx = m[val].top(); m[val].pop(); if (nums.size() - 1 != idx) { int t = nums.back(); nums[idx] = t; m[t].pop(); m[t].push(idx); } nums.pop_back(); return true; } /** Get a random element from the collection. */ int getRandom() { return nums[rand() % nums.size()]; }private: vector<int> nums; unordered_map<int, priority_queue<int>> m;};引用网址:http://www.cnblogs.com/grandyang/p/5756148.html
- 【数组】Leetcode编程题解:381. Insert Delete GetRandom O(1)
- 【数组】Leetcode编程题解:380. Insert Delete GetRandom O(1)
- leetcode题解-381. Insert Delete GetRandom O(1)
- leetcode 381. Insert Delete GetRandom O(1)
- leetcode 381. Insert Delete GetRandom O(1)
- [Leetcode] 381. Insert Delete GetRandom O(1)
- [leetcode]381. Insert Delete GetRandom O(1)
- leetcode 381. Insert Delete GetRandom O(1)
- leetcode题解-380. Insert Delete GetRandom O(1)
- LeetCode 380. Insert Delete GetRandom O(1) 题解
- 【leetcode】Insert Delete GetRandom O(1)
- 【Leetcode】Insert Delete GetRandom O(1)
- LeetCode[380] Insert Delete GetRandom O(1)
- Leetcode 之 Insert Delete GetRandom O(1)
- LeetCode:381 Insert Delete GetRandom O(1)
- leetcode之 Insert Delete GetRandom O(1)
- [leetcode] 380. Insert Delete GetRandom O(1)
- leetcode 380.Insert Delete GetRandom O(1)
- Present出来的页面Push到下一页
- 【PAT】1120. Friend Numbers
- Go语言学习之运算符(The way to go)
- LNK2001:无法解析的外部符号 "public: virtual struct CRuntimeClass *
- 读《Head First设计模式》学习到的学习方法
- 【数组】Leetcode编程题解:381. Insert Delete GetRandom O(1)
- 字节流中判断消息的边界
- gcc 4.9.4 编译
- IIS部署django,CSS消失问题/无法工作
- MySql常用命令集Mysql常用命令showdatabases;显示数据库createdatab
- DDE热连接OnAdvise
- HPUOJ Triangles
- 前端小白系列之——导言
- java的语言特性