题目
设计一个支持在平均 时间复杂度 O(1) 下,执行以下操作的数据结构。 insert(val):当元素 val 不存在时,向集合中插入该项。 remove(val):元素 val 存在时,从集合中移除该项。 getRandom:随机返回现有集合中的一项。每个元素应该有相同的概率被返回。
示例
①示例1
说明
①数据范围(自测)
②相关话题
③相似题目
④题目地址
解题方法
①哈希表
因为数据范围太大,无法用数组模拟的哈希表求解,但是可以使用 uthash 。 uthash 是一个用 C 语言编写的开源库,使用宏实现了哈希表的增删改查等功能。 虽然使用 uthash 可以实现常数时间插入、删除元素,但是无法实现常数时间获取随机元素。 所以我们还要再使用一个数组保存所有已插入的元素,以便于获取随机元素。并且要保证数组范围内的值都是有效的,即在插入元素时记录其数组下标值,以便在删除时,让数组中的最后一个元素填补这个删除空档。 时间复杂度:O(1)。 空间复杂度:O(N)。
代码详解
struct hash {
int key;
int value;
UT_hash_handle hh;
} ;
typedef struct {
int * arr;
int size;
struct hash* hashTable;
} RandomizedSet;
RandomizedSet* randomizedSetCreate ( ) {
RandomizedSet* r = malloc ( sizeof ( RandomizedSet) ) ;
r- > arr = malloc ( sizeof ( int ) * 5000 ) ;
r- > size = 0 ;
r- > hashTable = NULL ;
return r;
}
bool randomizedSetInsert ( RandomizedSet* obj, int val) {
struct hash * h;
HASH_FIND_INT ( obj- > hashTable, & val, h) ;
if ( ! h) {
h = malloc ( sizeof ( struct hash) ) ;
h- > key = val;
obj- > arr[ obj- > size] = val;
h- > value = obj- > size;
obj- > size++ ;
HASH_ADD_INT ( obj- > hashTable, key, h) ;
return true ;
}
return false ;
}
bool randomizedSetRemove ( RandomizedSet* obj, int val) {
struct hash * h1, * h2;
HASH_FIND_INT ( obj- > hashTable, & val, h1) ;
if ( h1) {
obj- > arr[ h1- > value] = obj- > arr[ obj- > size- 1 ] ;
HASH_FIND_INT ( obj- > hashTable, & obj- > arr[ obj- > size- 1 ] , h2) ;
h2- > value = h1- > value;
obj- > size-- ;
HASH_DEL ( obj- > hashTable, h1) ;
return true ;
}
return false ;
}
int randomizedSetGetRandom ( RandomizedSet* obj) {
return obj- > arr[ rand ( ) % obj- > size; ] ;
}
void randomizedSetFree ( RandomizedSet* obj) {
free ( obj- > arr) ;
free ( obj) ;
}
附录