每日一题 11.7 设计哈希映射

每日一题 11.7 设计哈希映射

一、题目概述

首先道个歉,昨天看S12总决赛去了,上午看完下午任务太多了,就只把题写了,没来写总结。。。那个题也不是太难,没什么好说的,就先不说了。

但是每日任务没完成,还是一个非常不好的行为TuT

今天这个题还是一道简单题,三天两道简单题,我还是蛮开心的,但是一直做简单题,我怕我的能力上不去,期待一下明天是我只是范围外的中档题。

这个题会涉及到一些之前哈希表的知识,有兴趣的可以翻一下第二篇每日一题看一下,那里介绍了一部分。

二、个人思路

设计哈希映射,我第一眼看到这个的时候,我的反应是,让我们自己设计函数嘛,那不是有很多种答案?然后看了一眼题,原来是让我们实现一些函数功能,有点像运算符重载。这个题型还是挺新颖的,实现成员函数。

我的代码如下:

class MyHashMap {
public:
    MyHashMap() {
    }

    vector<int> keys;
    vector<int> values;

    void put(int key, int value) {
        for(int i=0;i<keys.size();i++){
            if(keys[i]==key)
              values[i]=value;
            return;
        }
        keys.push_back(key);
        values.push_back(value);
        return ;
    }
    
    int get(int key) {
        for(int i=0;i<keys.size();i++){
            if(keys[i]==key)
              return values[i];
        }
        return -1;
    }
    
    void remove(int key) {
        for(int i=0;i<keys.size();i++){
            if(keys[i]==key){
                keys.erase(keys.begin()+i);
                values.erase(values.begin()+i);
                return ;
            }
        }
        return ;
    }
};

/**
 * Your MyHashMap object will be instantiated and called as such:
 * MyHashMap* obj = new MyHashMap();
 * obj->put(key,value);
 * int param_2 = obj->get(key);
 * obj->remove(key);
 */

我的思路简单粗暴,把哈希表看成几个并列的一维数组,相同下标标着同一组的key和value,然后三个函数分别对两个数组操作,简单易懂,就是时间复杂度估计不小,应该是O(n)这样,空间的话随着数据增加,我占的空间也多了。

但是还是,没把所有点都过去,应该是put出问题了,更新实现的不好。

三、大佬思路

这么说吧,基本我都没看懂,首先官方题解,给出来一大堆东西,我一点都没看懂,然后再看看其他人的题解,有用拉链法的,有用超大数组法的,我感觉拉链法和超大数组法都不是太好,所以我决定硬啃官方题解。

class MyHashMap {
private:
    vector<list<pair<int, int>>> data;
    static const int base = 769;
    static int hash(int key) {
        return key % base;
    }
public:
    /** Initialize your data structure here. */
    MyHashMap(): data(base) {}
    
    /** value will always be non-negative. */
    void put(int key, int value) {
        int h = hash(key);
        for (auto it = data[h].begin(); it != data[h].end(); it++) {
            if ((*it).first == key) {
                (*it).second = value;
                return;
            }
        }
        data[h].push_back(make_pair(key, value));
    }
    
    /** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
    int get(int key) {
        int h = hash(key);
        for (auto it = data[h].begin(); it != data[h].end(); it++) {
            if ((*it).first == key) {
                return (*it).second;
            }
        }
        return -1;
    }
    
    /** Removes the mapping of the specified value key if this map contains a mapping for the key */
    void remove(int key) {
        int h = hash(key);
        for (auto it = data[h].begin(); it != data[h].end(); it++) {
            if ((*it).first == key) {
                data[h].erase(it);
                return;
            }
        }
    }
};

时间复杂度:O(n/b)。其中 n 为哈希表中的元素数量,b 为链表的数量。假设哈希值是均匀分布的,则每个链表大概长度为 n/b  。

空间复杂度:O(n+b)。

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/design-hashmap/solution/she-ji-ha-xi-ying-she-by-leetcode-soluti-klu9/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

首先第一行那个套娃,我就没看懂,然后查了一下。vector不说了,list就是链表,pair是C++中一种模板类型。每个pair对象可以存储两个值,这两个值可以是不同的数据类型。存储的值可以是基本数据类型也可以是自定义数据类型。

以下一些内容参考C++中pair用法C++中vector,list,map用法

那这句话就是一个能存一对数据的链表所做成的vector,挺绕的,但是好好捋顺一下还是能看懂。

后面那个,设哈希表的大小为 base,则可以设计一个简单的哈希函数:hash(x)=x mod base。

我们开辟一个大小为 base 的数组,数组的每个位置是一个链表。当计算出哈希值之后,就插入到对应位置的链表当中。

由于我们使用整数除法作为哈希函数,为了尽可能避免冲突,应当将 \textit{base}base 取为一个质数。在这里,我们取 base=769。

data(base) 是一个vector的初始化,弄出来一个base这么大的vector。

下面那个auto是自动数据类型,他根据你后面的数值来确定你这个变量是什么类型,比如 auto a=5,那a就是int型。这里面的auto是迭代器型iterator,但那个for语句跟我写的也没什么区别,意思是一样的。

在下面的make_pair函数就是pair的一个简化,生成一对数据用的,要不然每次都要

pair<int,int>(1,1),太麻烦了,我们用 make_pair(1,1) ,能简单不少。

别的,感觉没什么好讲的了,这个代码,我第一眼看上去挺复杂,但是搜索一下慢慢学,还是能学懂,有的虽然没学过,但是看那个英语也能看懂。

看懂是一回事,希望下次我自己也能写出这样的代码。

四、总结

今天我们复习了一下vector的一些操作,然后给哈希表的一些操作自己实现了一遍,加深了印象。

新知识的话,我们了解了List,Pair这两个新的数据结构,然后学习了auto这一自动数据类型。list的相关操作有很多,和vector差不多,语法也差不多,想都学会都记住,是需要下功夫的,我们还是那个打法,遇到哪个就记哪个,慢慢学就好了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值