1. Problem Description
Design a data structure that supports all following operations in average O(1) time.
insert(val): Inserts an item val to the set if not already present.
remove(val): Removes an item val from the set if present.
getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned.
Example:
// Init an empty set.
RandomizedSet randomSet = new RandomizedSet();
// Inserts 1 to the set. Returns true as 1 was inserted successfully.
randomSet.insert(1);
// Returns false as 2 does not exist in the set.
randomSet.remove(2);
// Inserts 2 to the set, returns true. Set now contains [1,2].
randomSet.insert(2);
// getRandom should return either 1 or 2 randomly.
randomSet.getRandom();
// Removes 1 from the set, returns true. Set now contains [2].
randomSet.remove(1);
// 2 was already in the set, so return false.
randomSet.insert(2);
// Since 1 is the only number in the set, getRandom always return 1.
randomSet.getRandom();
实现三个函数:
1.插入函数(不存在方可插入)
2.删除元素(存在方可删除)
3.返回随机元素,每个元素被选中的概率应该相等(这个怎么judge没搞懂)
2. My solution
Two confusions:
1.Call function的部分给了一句这个
RandomizedSet randomSet = new RandomizedSet();
实际运行时报错:
error: conversion from 'RandomizedSet*' to non-scalar type 'RandomizedSet' requested|
可以改成:
RandomizedSet *randomSet=new RandomizedSet();//randomSet是指针
或者:
RandomizedSet randomSet;//randomSet是对象
2.每个元素被选中的概率应该相等
似乎call function的部分并没有验证概率问题,只验证返回的element是否在set中,所以我直接用了伪随机数也过了,正常应该用当前时间生成种子。
我用的是vector+map,vector实际存储set中的所有元素,map用来存储数字到其在vector中下标的映射关系。
※ 删除时,先把最后一个元素和要删除的对象的下标交换,再把实际数字交换,然后删除末位数字即可。
My code:
class RandomizedSet
{
public:
/** Initialize your data structure here. */
map<int ,int >hh;//哈希表,数字到下标映射
vector<int>nums;//实际的set
RandomizedSet()
{
hh.clear();
nums.clear();
}
/** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
bool insert(int val)
{
if(hh[val]==0)
{
int len=nums.size();
nums.push_back(val);
hh[val]=len+1;
return true;
}
else
return false;
}
/* Removes a value from the set. Returns true if the set contained the specified element. */
bool remove(int val)
{
if(hh[val]!=0)
{
//把末尾元素和删除元素交换,再删去末尾元素
int len=nums.size();
hh[nums[len-1]]=hh[val];
swap(nums[hh[val]-1],nums[len-1]);
//end返回末尾元素下一个的指针
vector<int>::iterator It=nums.end();
It--;
nums.erase(It);
hh[val]=0;
return true;
}
else
return false;
}
/** Get a random element from the set. */
int getRandom()
{
return nums[rand()%nums.size()+0];
}
};