力扣 454.四数相加II
题目链接/文章讲解/视频讲解:代码随想录
思路:将前两个数组中的元素两两相加,作为key值,同时统计key值重复出现的次数作为value,存入map数据类型中。然后将后两个数组两两相加,在umap中查找符合条件的key值,如果找到,将value值累加。最后返回count。
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
std::unordered_map <int,int> umap;
for(int a : nums1){
for(int b : nums2){
umap[a+b]++;
}
}
int count = 0;
for(int c : nums3){
for(int d : nums4){
if(umap.find(0-(c+d)) != umap.end())
{
count += umap[0-(c+d)];
}
}
}
return count;
}
};
因为感觉对unordered_map这种数据类型还有些不清晰,查找了以下资料:
unordered_map
是 C++ 标准模板库(STL)中的一种关联容器,用于存储键值对,其底层实现是哈希表。这使得unordered_map
可以提供非常快速的查找、插入和删除操作,通常为 O(1) 时间复杂度。以下是一些关于
unordered_map
的重要特点和使用方法:特点
- 无序性: 元素不会按键的大小顺序存储,而是根据哈希值来存储,因此无法通过遍历获得有序序列。
- 键唯一: 每个键都是唯一的,插入具有相同键的元素会替换旧的键值对。
- 快速访问: 由于哈希表的特点,对于大多数操作(查找、插入、删除)时间复杂度均为常数时间 O(1)。
- 哈希函数: 默认情况下使用标准的哈希函数,可以通过模板参数自定义哈希函数和比较函数。
代码示例
#include <iostream>
#include <unordered_map>
#include <string>
int main() {
// 创建一个 unordered_map,键类型为 std::string,值类型为 int
std::unordered_map<std::string, int> myMap;
// 插入键值对
myMap["apple"] = 10;
myMap["banana"] = 20;
myMap["orange"] = 30;
// 通过键来访问值
std::cout << "apple: " << myMap["apple"] << std::endl;
// 查找某个元素
std::string key = "banana";
auto it = myMap.find(key);
if (it != myMap.end()) {
std::cout << key << " found, value = " << it->second << std::endl;
} else {
std::cout << key << " not found" << std::endl;
}
// 遍历 unordered_map
for (const auto& pair : myMap) {
std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
}
// 删除一个元素
myMap.erase("orange");
// 检查删除结果
it = myMap.find("orange");
if (it == myMap.end()) {
std::cout << "orange has been deleted" << std::endl;
}
return 0;
}
- 包含头文件: 包含
<unordered_map>
头文件以使用unordered_map
。- 创建
unordered_map
: 创建一个名为myMap
的unordered_map
,其键类型为std::string
,值类型为int
。- 插入键值对: 使用
operator[]
来插入键值对,例如myMap["apple"] = 10
。- 访问值: 使用键来访问相应的值,例如
myMap["apple"]
。- 查找元素: 使用
find
方法来查找一个键,返回一个迭代器,如果键不存在则返回end()
。- 遍历
unordered_map
: 使用范围 for 循环来遍历unordered_map
。- 删除元素: 使用
erase
方法来删除某个键值对。
力扣 383. 赎金信
题目链接/文章讲解:代码随想录
思路:看到题目第一想法就是用map统计字母出现次数,忽略了只有26个字母用数组更好一些。先用数组统计一个字符串magzine的每个字母出现次数,然后循环遍历另一个字符串randomNote,每个字母出现时对数组中相应的次数值减一,如果值小于0,说明字母不够用,返回false。
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int record[26] = {0};
if (ransomNote.size() > magazine.size()) {
return false;
}
for(int i = 0; i < magazine.length(); i++){
record[magazine[i] - 'a']++;
}
for(int i = 0; i < ransomNote.length(); i++){
record[ransomNote[i] - 'a']--;
if(record[ransomNote[i] - 'a'] < 0){
return false;
}
}
return true;
}
};
看参考代码中使用了size()和length(),查询了一下两个并没有区别:
在C++中,针对
std::string
对象,size()
和length()
实际上是等效的,它们都返回字符串中字符的数量(即字符串的长度)。因此,在上述代码中,ransomNote.size()
和ransomNote.length()
以及magazine.size()
和magazine.length()
的使用是等效的,没有功能上的区别。
力扣 16 三数之和
题目链接/文章讲解/视频讲解:代码随想录