Data structure: insert, remove, contains, get random element, all at O(1)

后端 未结 14 594
别跟我提以往
别跟我提以往 2020-11-29 14:53

I was given this problem in an interview. How would you have answered?

Design a data structure that offers the following operations in O(1) time:

  • inse
相关标签:
14条回答
  • 2020-11-29 15:30

    Though this is way old, but since there's no answer in C++, here's my two cents.

    #include <vector>
    #include <unordered_map>
    #include <stdlib.h>
    
    template <typename T> class bucket{
        int size;
        std::vector<T> v;
        std::unordered_map<T, int> m;
    public:
        bucket(){
            size = 0;
            std::vector<T>* v = new std::vector<T>();
            std::unordered_map<T, int>* m = new std::unordered_map<T, int>();
        }
        void insert(const T& item){
            //prevent insertion of duplicates
            if(m.find(item) != m.end()){
                exit(-1);
            }
            v.push_back(item);
            m.emplace(item, size);
            size++;
    
        }
        void remove(const T& item){
            //exits if the item is not present in the list
            if(m[item] == -1){
                exit(-1);
            }else if(m.find(item) == m.end()){
                exit(-1);
            }
    
            int idx = m[item];
            m[v.back()] = idx;
            T itm = v[idx];
            v.insert(v.begin()+idx, v.back());
            v.erase(v.begin()+idx+1);
            v.insert(v.begin()+size, itm);
            v.erase(v.begin()+size);
            m[item] = -1;
            v.pop_back();
            size--;
    
        }
    
         T& getRandom(){
          int idx = rand()%size;
          return v[idx];
    
         }
    
         bool lookup(const T& item){
           if(m.find(item) == m.end()) return false;
           return true;
    
         }
        //method to check that remove has worked
        void print(){
            for(auto it = v.begin(); it != v.end(); it++){
                std::cout<<*it<<" ";
            }
        }
    };
    

    Here's a piece of client code to test the solution.

    int main() {
    
        bucket<char>* b = new bucket<char>();
        b->insert('d');
        b->insert('k');
        b->insert('l');
        b->insert('h');
        b->insert('j');
        b->insert('z');
        b->insert('p');
    
        std::cout<<b->random()<<std::endl;
        b->print();
        std::cout<<std::endl;
        b->remove('h');
        b->print();
    
        return 0;
    }
    
    0 讨论(0)
  • 2020-11-29 15:30

    I agree with Anon. Except for the last requirement where getting a random element with equal fairness is required all other requirements can be addressed only using a single Hash based DS. I will choose HashSet for this in Java. The modulo of hash code of an element will give me the index no of the underlying array in O(1) time. I can use that for add, remove and contains operations.

    0 讨论(0)
提交回复
热议问题