【哈希表】(三) 实际应用 - 哈希映射

目录

一、哈希映射 - 用法

二、场景 I - 提供更多信息

三、两数之和

3.1 题目要求

3.2 解决过程

四、同构字符串

4.1 题目要求

4.2 解决过程

四、两个列表的最小索引总和

4.1 题目要求

4.2 解决过程

六、场景 II - 按键聚合

七、字符串中的第一个唯一字符

7.1 题目要求

7.2 解决过程

八、两个数组的交集 II

8.1 题目要求

8.2 解决过程

九、存在重复元素 II

9.1 题目要求

9.2 解决过程

十、日志速率限制器 (PLUS 会员专享)


参考文献: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/


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值