705. Design HashSet

在这里插入图片描述

这一题意义还是很重大的,因为很可能面试的时候问你是怎么做的,或者有什么思路,能说几个是几个。

方法一:
针对这一题,因为元素大小有限制,所以可以直接申请一个这么大的数组,表示有没有。

class MyHashSet {
public:
    /** Initialize your data structure here. */
    MyHashSet():values(1000001, false) {
        
    }
    
    void add(int key) {
        values[key] = true;
    }
    
    void remove(int key) {
        values[key] = false;
    }
    
    /** Returns true if this set contains the specified element */
    bool contains(int key) {
        return values[key];
    }
private:
    vector<bool> values;
};

方法二:
如果数据范围不限制的话,可以使用二维表,其实还是使用了hash表,使用了类似拉链法来解决冲突,这里大小可以自己设定,根据数据量多少来设置,一般设定为素数

class MyHashSet {
public:
    /** Initialize your data structure here. */
    MyHashSet():table(sz, vector<int>()) {
        
    }
    
    void add(int key) {
        int idx = key % sz;
        for (int num : table[idx])
            if (num == key)
                return;
        table[idx].push_back(key);
    }
    
    void remove(int key) {
        int idx = key % sz;
        for (int i = 0; i < table[idx].size(); ++i) {
            if (table[idx][i] == key) {
                table[idx].erase(table[idx].begin()+i);
                return;
            }
        }
    }
    
    /** Returns true if this set contains the specified element */
    bool contains(int key) {
        int idx = key % sz;
        for (int num : table[idx]) 
            if (num == key)
                return true;
        return false;
    }
private:
    int sz = 1001;
    vector<vector<int>> table;
};

至于为什么使用素数:
待补充
https://blog.csdn.net/w_y_x_y/article/details/82288178
https://blog.csdn.net/maoliran/article/details/52082829

除数取合数的话,一旦数据是以合数的某个因子为间隔增长的,那么哈希值只会是几个值不停的重复,冲突很严重,而素数就不会发生这种情况。

方法三:
BST。也就是有序的map(红黑树和avl不会实现。。。)。这里的话优点是能够保证有序性,缺点是时间可能退化为线性

struct Node {
    Node(int v): val(v), left(nullptr), right(nullptr) {}
    int val;
    Node* left;
    Node* right;
};

class BST {
public:
    BST(): root(nullptr) {}
    
    void insert(int v) {
        root = insertHelper(root, v);
    }
    
    void erase(int v) {
        root = eraseHelper(root, v);
    }
    
    bool find(int v) {
        return findHelper(root, v);
    }
private:
    Node* root;
    
    Node* insertHelper(Node* node, int v) {
        if (!node)
            return new Node(v);
        if (node->val == v)
            return node;
        if (node->val > v)
            node->left = insertHelper(node->left, v);
        else 
            node->right = insertHelper(node->right, v);
        return node;
    }
    
    Node* eraseHelper(Node* node, int v) {
        if (!node)
            return nullptr;
        if (v < node->val)
            node->left = eraseHelper(node->left, v);
        else if (v > node->val)
            node->right = eraseHelper(node->right, v);
        else {
            Node* retNode = nullptr;
            if (!node->left) {
                retNode = node->right;
                delete node;
            } else if (!node->right) {
                retNode = node->left;
                delete node;
            } else {
                retNode = node->right;
                auto node2 = node->right;
                while (node2->left)
                    node2 = node2->left;
                node2->left = node->left;
                delete node;
            }
            node = retNode;
        }
        return node;
    }
    
    Node* findHelper(Node* node, int v) {
        if (!node)
            return nullptr;
        if (v < node->val)
            return findHelper(node->left, v);
        else if (v > node->val)
            return findHelper(node->right, v);
        else 
            return node;
    }
};



class MyHashSet {
public:
    /** Initialize your data structure here. */
    MyHashSet(): bst(new BST()) {
        
    }
    
    void add(int key) {
        bst->insert(key);
    }
    
    void remove(int key) {
        bst->erase(key);
    }
    
    /** Returns true if this set contains the specified element */
    bool contains(int key) {
        return bst->find(key);
    }
private:
    BST* bst;
};
posted @ 2019-10-06 17:28  于老师的父亲王老爷子  阅读(14)  评论(0)    收藏  举报