目录
参考文献:https://leetcode-cn.com/leetbook/read/hash-table/xhly3j/
一、哈希映射 - 用法
// C++ implementation
#include <unordered_map> // 0. include the library
int main() {
// 1. initialize a hash map
unordered_map<int, int> hashmap;
// 2. insert a new (key, value) pair
hashmap.insert(make_pair(0, 0));
hashmap.insert(make_pair(2, 3));
// 3. insert a new (key, value) pair or update the value of existed key
hashmap[1] = 1;
hashmap[1] = 2;
// 4. get the value of a specific key
cout << "The value of key 1 is: " << hashmap[1] << endl;
// 5. delete a key
hashmap.erase(2);
// 6. check if a key is in the hash map
if (hashmap.count(2) <= 0) {
cout << "Key 2 is not in the hash map." << endl;
}
// 7. get the size of the hash map
cout << "the size of hash map is: " << hashmap.size() << endl;
// 8. iterate the hash map
for (auto it = hashmap.begin(); it != hashmap.end(); ++it) {
cout << "(" << it->first << "," << it->second << ") ";
}
cout << "are in the hash map." << endl;
// 9. clear the hash map
hashmap.clear();
// 10. check if the hash map is empty
if (hashmap.empty()) {
cout << "hash map is empty now!" << endl;
}
}
# Python implementation
# 1. initialize a hash map
hashmap = {0 : 0, 2 : 3}
# 2. insert a new (key, value) pair or update the value of existed key
hashmap[1] = 1
hashmap[1] = 2
# 3. get the value of a key
print("The value of key 1 is: " + str(hashmap[1]))
# 4. delete a key
del hashmap[2]
# 5. check if a key is in the hash map
if 2 not in hashmap:
print("Key 2 is not in the hash map.")
# 6. both key and value can have different type in a hash map
hashmap["pi"] = 3.1415
# 7. get the size of the hash map
print("The size of hash map is: " + str(len(hashmap)))
# 8. iterate the hash map
for key in hashmap:
print("(" + str(key) + "," + str(hashmap[key]) + ")", end=" ")
print("are in the hash map.")
# 9. get all keys in hash map
print(hashmap.keys())
# 10. clear the hash map
hashmap.clear();
print("The size of hash map is: " + str(len(hashmap)))
参考文献:https://leetcode-cn.com/leetbook/read/hash-table/xhy35e/
二、场景 I - 提供更多信息
// C++ implementation
/*
* Template for using hash map to find duplicates.
* Replace ReturnType with the actual type of your return value.
*/
ReturnType aggregateByKey_hashmap(vector<Type>& keys) {
// Replace Type and InfoType with actual type of your key and value
unordered_map<Type, InfoType> hashtable;
for (Type key : keys) {
if (hashmap.count(key) > 0) {
if (hashmap[key] satisfies the requirement) {
return needed_information;
}
}
// Value can be any information you needed (e.g. index)
hashmap[key] = value;
}
return needed_information;
}
参考文献:https://leetcode-cn.com/leetbook/read/hash-table/xhcuhg/
三、两数之和
3.1 题目要求
3.2 解决过程
个人实现
法一:朴素法 - 暴力迭代法。空间复杂度 O(1),时间复杂度 O(n²)。
2020/08/21 - 26.06% (3552ms)
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
for i in range(len(nums)-1): # 当前数值
cur = target - nums[i] # 待寻找数值
for j in range(i+1, len(nums)): # 被比较数值
if cur == nums[j]:
return [i, j]
法二:散列表 / 哈希表。牺牲空间换取时间。结合题目和提示可使用字典形式的哈希表实现 (当然,由全0初始化列表构造的 HashTable 亦可)。
具体而言,先用 target 减去列表中的首个元素值,并将该元素值作为 key、元素值的下标/索引作为 value 存入字典。接着 target 依次减去列表中的其余元素值,并判断差是否作为 key 存在于字典中。若存在,则表示列表中存在两值之和等于 target,此时可直接返回答案,即 key 对应的 value 及当前元素值的 index。若不存在,则同理将该元素值及其索引作为 <key, value> 存入字典。通过字典存储可以实现去重。空间复杂度 O(n),时间复杂度 O(n)。
2020/08/21 - 97.22% (56ms) - 最佳
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hashmap = {} # 字典形式的 hashmap (使用全0初始化的列表也可以)
for index, num in enumerate(nums):
cur = target-num
if cur in hashmap:
return [hashmap[cur], index] # 找到两数之和满足, 返回二者 index
else:
hashmap[num] = index # 否则, 将当前元素及其索引作为 key-value 加入 hashmap
判断值是否在某个容器 (container) 中,能做到 O(1) 时间复杂度查找 的便是最常用的 散列表 (HashTable), Python 内置数据类型中的字典即是。就本题而言,key 为标记元素值,value 为元素值下标/索引,所以更加确定使用字典这个数据结构。
此外,若使用 Python 内置 index() 函数,则因其复杂度为 O(n) 将使整个程序的复杂度达到 O(n²) (结合外层 for 循环的 O(n));若选择使用两个 for 循环,则虽然能取得 O(1) 的空间复杂度,但却将达到 O(n²) 的时间复杂度;此二者均为低效的解法,而使用散列表则能够实现 牺牲空间换取时间,且实际中能找到节省时间的解往往更有价值。
参考文献
https://leetcode-cn.com/problems/two-sum/submissions/