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;
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章