代码随想录: 代码随想录
454. 四数相加 II
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
int res = 0;
map<int, int> map;
for (auto a : nums1) {
for (auto b : nums2) {
map[a + b]++;
}
}
for (auto c : nums3) {
for (auto d : nums4) {
if (map.find(-1 * (c + d))!= map.end()) {
res += map[-1 * (c + d)];
}
}
}
return res;
}
};
疑问:
//1
if (map.find(-1 * (c + d)) != map.end()) {
res += map[-1 * (c + d)];
}
// 2
auto it = map.find(-1 * (c + d));
if (it != map.end()) {
res += it->second;
}
这两种做法有什么区别
以下是Claude sonnet 3.5的回答:
这两种做法在功能上是等价的,但在效率和代码风格上有一些微小的区别:
-
效率:
第一种方法:
if (map.find(-1 * (c + d))!= map.end()) { res += map[-1 * (c + d)]; }
这种方法实际上进行了两次查找操作:一次在
find()
中,另一次在使用[]
操作符时。第二种方法:
auto it = map.find(-1 * (c + d)); if (it != map.end()) { res += it->second; }
这种方法只进行了一次查找操作,然后直接使用找到的迭代器。
-
安全性:
第一种方法中,如果键不存在,
[]
操作符会创建一个新的键值对。虽然在这个特定的情况下不会发生(因为我们已经检查了键是否存在),但这种用法可能在其他情况下导致意外行为。第二种方法更安全,因为它不会意外地创建新的键值对。
-
代码风格:
第二种方法被认为是更好的C++风格。它更明确地表达了意图,并且避免了重复查找。
-
性能:
对于
std::map
,两种方法的性能差异可能不太明显,因为std::map
的[]
操作符通常被优化得很好。但对于
std::unordered_map
,第二种方法可能会有轻微的性能优势,因为它避免了第二次哈希计算。
总的来说,第二种方法(使用迭代器)是更推荐的做法。它更高效(只查找一次),更安全(不会意外创建新元素),并且符合 C++ 的惯用做法。在处理大量数据或者对性能要求较高的场景中,这种小的优化可能会产生明显的影响。
您对这个解释还有什么疑问吗?或者您想了解更多关于 C++ 容器操作的最佳实践?
383. 赎金信
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int a[26] = {0};
for (auto c : magazine) {
a[c - 'a']++;
}
for (auto c : ransomNote) {
a[c - 'a']--;
if (a[c - 'a'] < 0) {
return false;
}
}
return true;
}
};