1、常数时间插入、删除和获取随机元素
设计一个支持在平均时间复杂度 O(1)下,执行以下操作的数据结构。
insert(val):当元素 val 不存在时,向集合中插入该项。
remove(val):元素 val 存在时,从集合中移除该项。
getRandom:随机返回现有集合中的一项。每个元素应该有相同的概率被返回。
解题思路:hashmap用来key->index(vector的索引位置),vector用来存储key值。插入比较简单,使用hashmap是映射索引便于在O(1)时间可以删除vector所对应的元素。
链接:https://leetcode-cn.com/problems/insert-delete-getrandom-o1/solution/shi-yong-hashmaphe-vectorshi-xian-cji-bai-93-by-zh/
class RandomizedSet {
public:
map<int,int>mymap;
vector<int>index;
/** Initialize your data structure here. */
RandomizedSet() {
}
/** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
bool insert(int val) {
auto it=mymap.find(val);
//存在,返回false
if(it!=mymap.end())return false;
//不存在,插入,返回true
mymap[val]=index.size();
index.push_back(val);
return true;
}
/** Removes a value from the set. Returns true if the set contained the specified element. */
bool remove(int val) {
auto it=mymap.find(val);
//不存在,返回false
if(it==mymap.end())return false;
//存在val,移出,返回ture
int size=index.size();
int loc=mymap[val];
mymap[index[size-1]]=loc;
index[loc]=index[size-1];
index.pop_back();
mymap.erase(val);
return true;
}
/** Get a random element from the set. */
int getRandom() {
int size=index.size();
if(!size)return 0;
int ind=rand()%size;
return index[ind];
}
};
/**
* Your RandomizedSet object will be instantiated and called as such:
* RandomizedSet* obj = new RandomizedSet();
* bool param_1 = obj->insert(val);
* bool param_2 = obj->remove(val);
* int param_3 = obj->getRandom();
*/
2、四数相加 II
给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。
为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500 。所有整数的范围在 -228 到 228 - 1 之间,最终结果不会超过 231 - 1 。
解答:哈希表 H<A[i]+B[j],计数>。对 A[i]+B[j] 的值进行计数。计算 t=C[u]+D[v]。如果 H 中有 -t,那么, A[i]+B[j] + C[u]+D[v] == 0。multiset来模拟哈希表因为内部用红黑树排序,取数时使用 count() 花费较大,用纯哈希表map<int, int>就可以通过了。
作者:fxxuuu
链接:https://leetcode-cn.com/problems/4sum-ii/solution/c-ji-yi-hua-sou-suo-ha-xi-cha-biao-fa-by-fxxuuu/
class Solution {
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
if(A.empty() || B.empty() || C.empty() || D.empty())return 0;
map<int,int>ab;
for(int a:A)
{
for(int b:B)
{
ab[a+b]++;
}
}
int ans=0;
for(int c:C)
{
for(int d:D)
{
ans+=ab[-(c+d)];
}
}
return ans;
}
};