哈希表
454.两数相加
unordered_map
迭代器
begin,cbegin (C++11)返回指向起始的迭代器(公开成员函数)
end,cend (C++11)返回指向末尾的迭代器(公开成员函数)
容量
empty (C++11)检查容器是否为空(公开成员函数)
size (C++11)返回容纳的元素数(公开成员函数)
修改器
clear (C++11)清除内容(公开成员函数)
insert (C++11) 插入元素或结点 (C++17 起)(公开成员函数)
erase (C++11)擦除元素(公开成员函数)
查找
find (C++11)寻找带有特定键的元素(公开成员函数)
contains (C++20)检查容器是否含有带特定键的元素(公开成员函数)
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
//将nums1,nums2的和存入哈希表中,之后遍历nums3,nums4判断是否存在-nums3-nums4
//因为存在重复的和,且需要记录重复的次数,因此使用unordered_map,查找复杂度为O(1)
std::unordered_map<int,int> map;
for(int i = 0;i < nums1.size();i++){
for(int j = 0;j < nums2.size();j++){
auto search = map.find(nums1[i]+nums2[j]);//O(1)
if(search == map.end())map.insert({nums1[i]+nums2[j],1});
else ++search->second;
}
}
int count = 0;
for(int i = 0;i < nums3.size();i++){
for(int j = 0;j < nums4.size();j++){
auto search = map.find(0-nums3[i]-nums4[j]);
if(search != map.end())count+= search->second;
}
}
return count;
}
};//O(n^2)
383.赎金信
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int nums[26] = {0};//一共只有26个元素,因此可以使用数组实现哈希表,
//存储magazine中字母出现的次数
for(int i = 0;i < magazine.size();i++){
nums[magazine[i]-'a']++;
}
for(int i = 0;i < ransomNote.size();i++){
if(--nums[ransomNote[i]-'a'] < 0)return false;
}
return true;
}
};//O(n)
15.三数之和
暴力解
```C++
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> ans;
//排序之后,三元组每个位置的元素和上一次枚举的元素不同时,才枚举
for(int i = 0;i < nums.size();i++){
if(nums[i] > 0)break;
if(i > 0 && nums[i] == nums[i-1])continue;//a去重
for(int j = i+1;j < nums.size();j++){
if(j > i+1 &&nums[j] == nums[j-1])continue;//b去重
for(int k = j+1;k < nums.size();k++){
if(k > j+1 && nums[k] == nums[k-1])continue;//c去重
if(nums[i]+nums[j]+nums[k] ==0)
ans.push_back({nums[i],nums[j],nums[k]});
}
}
}
return ans;
}
};//O(n^3)
```
双指针:将两层for循环将为一层for
当j向后移动一个位置的时候,k向前移动若干位置
```C++
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> ans;
int len = nums.size();
//排序之后,三元组每个位置的元素和上一次枚举的元素不同时,才枚举
for(int i = 0;i < nums.size();i++){
if(nums[i] > 0)break;
if(i > 0 && nums[i] == nums[i-1])continue;//a去重
int k = len-1;
for(int j = i+1;j < nums.size();j++){
if(j > i+1 && nums[j] == nums[j-1])continue;//b去重
while(j < k&&nums[i]+nums[j]+nums[k] > 0)k--;
//c的去重随着b的去重,一同被去重
if(j == k)break;
if(nums[i]+nums[j]+nums[k] == 0)
ans.push_back({nums[i],nums[j],nums[k]});
}
}
return ans;
}
};//O(n^2)
```
18、四数之和
暴力解
```C++
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
vector<vector<int>> ans;
for(int i = 0;i < nums.size();i++){
if(i > 0 && nums[i] == nums[i-1])continue;
for(int j = i+1;j < nums.size();j++){
if(j > i+1 && nums[j] == nums[j-1])continue;
for(int k = j+1;k < nums.size();k++){
if(k > j+1 && nums[k] == nums[k-1])continue;
for(int l = k+1;l < nums.size();l++){
if(l > k+1 && nums[l] == nums[l-1])continue;
long sum = (long)nums[i]+nums[j]+nums[k]+nums[l];
if(sum == target)
ans.push_back({nums[i],nums[j],nums[k],nums[l]});
}
}
}
}
return ans;
}
};//O(n^4)
使用双指针降低复杂度
```C++
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
vector<vector<int>> ans;
for(int i = 0;i < nums.size();i++){
if(i > 0 && nums[i] == nums[i-1])continue;//去重
for(int j = i+1;j < nums.size();j++){
if(j > i+1 && nums[j] == nums[j-1])continue;//
int l = nums.size() - 1;
for(int k = j+1;k < nums.size();k++){//双指针代替两重循环
if(k > j+1 && nums[k] == nums[k-1])continue;//
while(k < l && (long)nums[i]+nums[j]+nums[k]+nums[l] > target)l--;
if(l == k)break;
if((long)nums[i]+nums[j]+nums[k]+nums[l] == target)
ans.push_back({nums[i],nums[j],nums[k],nums[l]});
}
}
}
return ans;
}
};//O(n^3)