From e552116d765e6f39d9d81b73cb8ceb9e6f43d4da Mon Sep 17 00:00:00 2001 From: Sainnhe Park Date: Sat, 3 Dec 2022 10:38:05 +0800 Subject: [PATCH] s0454 --- include/s0454_4sum.hpp | 15 +++++++++++ notes/src/SUMMARY.md | 5 ++++ notes/src/four_sum_ii.md | 11 ++++++++ notes/src/hash_table.md | 56 ++++++++++++++++++++++++++++++++++++++++ src/s0454_4sum.cpp | 31 ++++++++++++++++++++++ tests/s0454_4sum.cpp | 23 +++++++++++++++++ 6 files changed, 141 insertions(+) create mode 100644 include/s0454_4sum.hpp create mode 100644 notes/src/four_sum_ii.md create mode 100644 notes/src/hash_table.md create mode 100644 src/s0454_4sum.cpp create mode 100644 tests/s0454_4sum.cpp diff --git a/include/s0454_4sum.hpp b/include/s0454_4sum.hpp new file mode 100644 index 0000000..1d3a80c --- /dev/null +++ b/include/s0454_4sum.hpp @@ -0,0 +1,15 @@ +#ifndef S0454_4SUM_HPP +#define S0454_4SUM_HPP + +#include +#include + +using namespace std; + +class S0454 { + public: + int fourSumCount(vector& nums1, vector& nums2, vector& nums3, + vector& nums4); +}; + +#endif diff --git a/notes/src/SUMMARY.md b/notes/src/SUMMARY.md index dbabb01..ad60c90 100644 --- a/notes/src/SUMMARY.md +++ b/notes/src/SUMMARY.md @@ -12,6 +12,11 @@ - [总结](./linked_list.md) - [环形链表](./linked_list_cycle.md) +# 哈希表 + +- [总结](./hash_table.md) +- [四数相加 II](./four_sum_ii.md) + # 字符串 - [总结](./string.md) diff --git a/notes/src/four_sum_ii.md b/notes/src/four_sum_ii.md new file mode 100644 index 0000000..34540c3 --- /dev/null +++ b/notes/src/four_sum_ii.md @@ -0,0 +1,11 @@ +# 四数相加 II + +[Leetcode](https://leetcode.com/problems/4sum-ii/) + +这是一道经典的哈希表的题。 + +双重循环遍历 A 和 B ,把 `A[i] + B[j]` 作为 key ,把出现的次数作为 value 。 + +同样地遍历 C 和 D 。 + +那么现在就得到了两个哈希表了,遍历哈希表,看看是否有两个值之和为 0 ,如果有的话统计出现的次数。 diff --git a/notes/src/hash_table.md b/notes/src/hash_table.md new file mode 100644 index 0000000..26f0319 --- /dev/null +++ b/notes/src/hash_table.md @@ -0,0 +1,56 @@ +# 总结 + +当我们需要判断某个元素是否出现过时,考虑用哈希表。 + +## unordered_map 与 unordered_set + +这俩的底层都是用哈希函数实现的,因此访问其中的元素可以达到 O(1) 的时间复杂度。 + +它们的区别在于,unordered_map 存储的是 key-value ,而 unordered_set 只存储 key 。 + +一般我们直接用 unordered_map 就可以完成所有操作了。 + +常见用法: + +```cpp +#include +#include +#include + +int main(int argc, const char *argv[]) { + // key 为 std::string 类型的,value 为 int 类型的 + std::unordered_map map; + // 插入 + map["foo"] = 1; + map["bar"] = 2; + map["non"] = 3; + // 访问 + std::cout << map["foo"] << std::endl; + // 删除 + map.erase("foo"); + // 判断元素是否存在 + if (map.count("bar") > 0) { + std::cout << "Exist" << std::endl; + } else { + std::cout << "Not exist" << std::endl; + } + // 另一种判断元素是否存在的方法 + // find() 会返回元素的正向迭代器,如果没找到则返回 end() + if (map.find("bar") != map.end()) { + std::cout << "Exist" << std::endl; + } else { + std::cout << "Not exist" << std::endl; + } + // 合并两个 unordered_map + std::unordered_map newMap; + newMap["microsoft"] = 1; + newMap["surface"] = 1; + map.insert(newMap.begin(), newMap.end()); + // 遍历 + for (std::unordered_map::iterator iter = map.begin(); + iter != map.end(); ++iter) { + std::cout << iter->first << iter->second << std::endl; + } + return 0; +} +``` diff --git a/src/s0454_4sum.cpp b/src/s0454_4sum.cpp new file mode 100644 index 0000000..fddcb65 --- /dev/null +++ b/src/s0454_4sum.cpp @@ -0,0 +1,31 @@ +#include "s0454_4sum.hpp" + +int S0454::fourSumCount(vector& nums1, vector& nums2, + vector& nums3, vector& nums4) { + unordered_map map1, map2; + for (int i{0}; i < nums1.size(); ++i) { + for (int j{0}; j < nums2.size(); ++j) { + if (map1.count(nums1[i] + nums2[j]) > 0) { + ++map1[nums1[i] + nums2[j]]; + } else { + map1[nums1[i] + nums2[j]] = 1; + } + } + } + for (int i{0}; i < nums3.size(); ++i) { + for (int j{0}; j < nums4.size(); ++j) { + if (map2.count(nums3[i] + nums4[j]) > 0) { + ++map2[nums3[i] + nums4[j]]; + } else { + map2[nums3[i] + nums4[j]] = 1; + } + } + } + int cnt{0}; + for (unordered_map::iterator iter = map1.begin(); iter != map1.end(); ++iter) { + if (map2.count(-iter->first) > 0) { + cnt += iter->second * map2[-iter->first]; + } + } + return cnt; +} diff --git a/tests/s0454_4sum.cpp b/tests/s0454_4sum.cpp new file mode 100644 index 0000000..637a28d --- /dev/null +++ b/tests/s0454_4sum.cpp @@ -0,0 +1,23 @@ +#include "s0454_4sum.hpp" + +#include + +TEST(Problem454, Case1) { + vector nums1{1, 2}; + vector nums2{-2, -1}; + vector nums3{-1, 2}; + vector nums4{0, 2}; + int expected{2}; + S0454 solution; + EXPECT_EQ(solution.fourSumCount(nums1, nums2, nums3, nums4), expected); +} + +TEST(Problem454, Case2) { + vector nums1{0}; + vector nums2{0}; + vector nums3{0}; + vector nums4{0}; + int expected{1}; + S0454 solution; + EXPECT_EQ(solution.fourSumCount(nums1, nums2, nums3, nums4), expected); +}