1、插入、删除和随机访问
题目描述: 设计一个支持在平均 时间复杂度 O(1) 下,执行以下操作的数据结构:
- insert(val):当元素 val 不存在时返回 true ,并向集合中插入该项,否则返回 false 。
- remove(val):当元素 val 存在时返回 true ,并从集合中移除该项,否则返回 false 。
- getRandom:随机返回现有集合中的一项。每个元素应该有 相同的概率 被返回。
题目链接: 插入、删除和随机访问传送门 WA code 样例通过了17/19,getRandom()使用srand的话输出的并不满足随机且概率相等这个条件
class RandomizedSet {
struct Node{
int val;
Node* next=NULL;
};
public:
Node*head=NULL;
int len=0;
int total=0;
RandomizedSet() {
head=new Node;
total++;
}
bool insert(int val) {
Node*p=head->next;
Node*pre=head;
total++;
while(p!=NULL){
if(p->val==val){
return false;
}
if(p->val>val){
Node*node=new Node;
node->val=val;
pre->next=node;
node->next=p;
break;
}
pre=p;
p=p->next;
}
Node*node=new Node;
node->val=val;
pre->next=node;
node->next=p;
len++;
return true;
}
bool remove(int val) {
total++;
Node*p=head->next;
Node*pre=head;
while(p!=NULL){
if(p->val==val){
pre->next=p->next;
delete(p);
len--;
return true;
}
pre=p;
p=p->next;
}
return false;
}
int getRandom() {
total++;
int pos=total%len;
Node*p=head->next;
int cnt=0;
while(p!=NULL){
if(cnt==pos){
return p->val;
}else{
p=p->next;
cnt++;
}
}
return -1;
}
};
官方题解 为了满足插入、删除和随机访问元素操作的时间复杂度都是 O(1),需要将变长数组和哈希表结合,变长数组中存储元素,哈希表中存储每个元素在变长数组中的下标. 学习了C++类的写法~ 同时一些效率优化见code中的注释:
- emplace_back()
- 哈希表的.count()
class RandomizedSet {
public:
RandomizedSet() {
srand((unsigned)time(NULL));
}
bool insert(int val) {
if(find(vec.begin(),vec.end(),val)!=vec.end()){
return false;
}else{
vec.push_back(val);
hash_table[val]=len;
len++;
return true;
}
}
bool remove(int val) {
if(find(vec.begin(),vec.end(),val)==vec.end()){
return false;
}else{
int pos=hash_table[val];
hash_table[vec[len-1]]=pos;
swap(vec[len-1],vec[pos]);
len--;
vec.pop_back();
hash_table.erase(val);
return true;
}
}
int getRandom() {
int pos=rand()%len;
return vec[pos];
}
private:
unordered_map<int,int>hash_table;
vector<int>vec;
int len=0;
};
2、LRU
题目描述: 题目链接: AC代码 时间复杂度和空间复杂度控制得都不是很好……但是还是很容易看懂思路:
cnts 用来存储当前key值上一次被使用时的时间,全局变量cur_time 在每次执行函数的时候自增以记录时间mp 用来记录key:value的对应关系
class LRUCache {
public:
int Capacity;
int cur_capacity=0;
int cur_time=0;
map<int,int>mp;
map<int,int>cnts;
LRUCache(int capacity) {
Capacity=capacity;
}
int get(int key) {
cur_time++;
if(mp.find(key)!=mp.end()){
cnts[key]=cur_time;
return mp[key];
}else{
return -1;
}
}
void put(int key, int value) {
cur_time++;
if(mp.find(key)!=mp.end()){
cnts[key]=cur_time;
mp[key]=value;
}else{
if(cur_capacity<Capacity){
cur_capacity++;
cnts[key]=cur_time;
mp[key]=value;
}else{
int tkey,min_time=INT_MAX;
for(map<int,int>::iterator it=cnts.begin();it!=cnts.end();it++){
if(it->second<min_time){
min_time=it->second;
tkey=it->first;
}
}
cnts.erase(tkey);
mp.erase(tkey);
cnts[key]=cur_time;
mp[key]=value;
}
}
}
};
|