美文网首页
设计哈希映射 + 删除并获得点数

设计哈希映射 + 删除并获得点数

作者: 吃掉夏天的怪物 | 来源:发表于2021-07-11 21:34 被阅读0次

    706. 设计哈希映射

    没有想到resize可以这样用,要不然就做不出来了~
    链地址法还没有熟练掌握。

    方法一 自己瞎写的用vector

    这里因为题目说0 <= key, value <= 10^6,才能用key当index这样做,但凡有小于0的key这个方法就不适用了。

    class MyHashMap {
    public:
        /** Initialize your data structure here. */
        vector<int> fakeH;
        MyHashMap() {
    
        }
        
      
      /** value will always be non-negative. */
        void put(int key, int value) {
            if(fakeH.size() <= key){
                fakeH.resize(key+1,-1);
            }
            fakeH[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) {
            if(key < fakeH.size() && fakeH[key]!=-1) return fakeH[key];
            else return -1;
        }
        
        /** Removes the mapping of the specified value key if this map contains a mapping for the key */
        void remove(int key) {
            if(key < fakeH.size())
            fakeH[key] = -1;
        }
    };
    
    /**
     * 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);
     */
    

    方法二 链地址法

    ⭐ C++ list的用法

    本题考查我们对于实现哈希表,有哪些方法,分别有什么利弊?
    实现哈希表的原理,其实我们会遇到一个抉择,那就是时间和空间的取舍。
    实现方式有两种:
    超大数组:不考虑空间复杂度,创建超大数组,每个数都能单独存入,且不会位置冲突。
    链地址法:空间/时间的最佳实践,基于数组实现,并且通过一个 hashhash 函数生成一个对应的索引,当多个数索引一致的时候,再处理冲突问题,一般我们使用链地址法解决冲突。

    class MyHashMap {
    private:
        vector<list<pair<int, int>>> data;
        static const int base = 769;
        static int hash(int key) {
            return key % base;
        }
    public:
        MyHashMap(): data(base) {}
        
        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));
        }
        
        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;
        }
        
        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;
                }
            }
        }
    };
    
    

    740. 删除并获得点数

    这道题可以算打家劫舍的plus版本,也是选定一个数字,与它相邻的两个数字带来的增益点数就不能算了。
    但是把它转变成打家劫舍问题,首先得创建一个数组,数组的index表示,待删除的数,vals[index]表示删除这个数所获得的增益值是多少。

    方法一 转变为打家劫舍问题

    class Solution {
    public:
        int robe(vector<int>&nums){
            int n = nums.size();
            int a = nums[0], b = max(nums[0],nums[1]);
            for(int i = 2; i < n; i++){
                int t = max(a+(nums[i]),b);
                a = b;
                b = t;
            }
            return b;
        }
        int deleteAndEarn(vector<int>& nums) {
            int n = nums.size();
            if(n == 1) return nums[0];
            int maxVal = 0;
            for(auto it:nums){
                maxVal = max(maxVal,it);
            }
            vector<int> vals(maxVal+1,0);
            for(auto it:nums){
                vals[it]+=it;
            }
            return robe(vals);
        }
    };
    

    时间复杂度:O(N+M),其中 N 是数组nums 的长度,M 是 nums 中元素的最大值。

    空间复杂度:O(M)。

    方法二 排序+动态规划

    class Solution {
    public:
        int robe(vector<int>&nums){
            int n = nums.size();
            // if(n == 0) return 0;
            if(n == 1) return nums[0];
            int a = nums[0], b = max(nums[0],nums[1]);
            for(int i = 2; i < n; i++){
                int t = max(a+(nums[i]),b);
                a = b;
                b = t;
            }
            return b;
        }
        int deleteAndEarn(vector<int>& nums) {
            int n = nums.size();
            if(n == 1) return nums[0];
            int maxVal = 0;
            sort(nums.begin(),nums.end());
            vector<int> sums = {nums[0]};
            int ans = 0;
            for(int i =1; i< n; i++){
                int val = nums[i];
                if(val == nums[i-1]){
                    sums.back() += val;
                }else if(val == nums[i-1]+1){
                    sums.push_back(val);
                }else{
                    ans += robe(sums);
                    sums = {val};
                }
            }
            return ans+robe(sums);
        }
    };
    
    image.png

    相关文章

      网友评论

          本文标题:设计哈希映射 + 删除并获得点数

          本文链接:https://www.haomeiwen.com/subject/yjzzultx.html