Heavily commented JavaScript bucket solution
\n\n/**\n * Initialize your data structure here.\n */\n\nfunction ListNode(val) {\n    this.val = val;\n    this.next = null;\n}\n\nvar MyHashSet = function() {
```\n\n/**\n * Initialize your data structure here.\n */\n\nfunction ListNode(val) {\n    this.val = val;\n    this.next = null;\n}\n\nvar MyHashSet = function() {\n    /* a hashset eh? \n     At first I thought we\'d have to make our own hashing function, but\n     we\'re getting numbers as input, so it\'s already a unique mapping\n     Should we just create an array of size 1*10^6?\n     \n     Took a look at discuss, some drama there. Some camps say you should\n     do the real thing, others think you should always take the notes into\n     account.\n     \n     I think https://leetcode.com/explore/featured/card/august-leetcoding-challenge/549/week-1-august-1st-august-7th/3410/discuss/356633/javaScript-solution-using-buckets-and-linked-list\n     \n     Makes a nice point, we should try to do the real-ish thing.\n     \n     Which seems to do a simple mod operation to "hash" the number\n     \n     and you then purposely create colisions, which you handle by having each entry \n     be a ll. The author of that page starts each with head(0) which I don\'t get why\n     \n     Ill try to make it without that and see how it goes.\n     \n     -- coding --\n     \n     works with the given input, and I like the node insert and deletion better than \n     the above example. less to explain to a new reader.\n     \n     Going to see if there are more test cases.\n     \n     https://leetcode.com/explore/featured/card/august-leetcoding-challenge/549/week-1-august-1st-august-7th/3410/discuss/249425/A-big-LeetCode-TestCase\n     \n     has a nice long one, and it succeeds!\n     \n     Submitted but an error on test case 24\n     \n     I made a mistake in add:\n     \n        // if not, append it\n        node.next = new ListNode(key);\n        \n    at this point, node.next could be null, so I should keep track of the last node\n  \n     \n     */\n    \n    // To make this as real as possible, we determine the size before hand\n    this.size = 1000\n    this.arr = new Array(this.size);\n    \n};\n\n/** \n * @param {number} key\n * @return {void}\n */\nMyHashSet.prototype.hash = function(key) {\n    // to make sure everyone ends up in a bucket\n    \n    return key % this.size;\n}\nMyHashSet.prototype.add = function(key) {\n    const hash = this.hash(key);\n    \n    // First see if we\'ve got this bucket at all created\n    if (!this.arr[hash]) {\n        this.arr[hash] = new ListNode(key);\n    } else {\n        // If the bucket exists, we need to follow the LL to see if it\'s in there\n        let head = this.arr[hash]; // we don\'t need head really, but I like it for clarity\n        let node = head;\n        let last; // we\'ll keep track of the previous node for tying the ll back together\n        \n        while (node) {\n            if (node.val === key) {\n                return;\n            }\n            last = node;\n            node = node.next;\n        }\n        \n        // if not, append it\n        last.next = new ListNode(key);\n    }\n};\n\n/** \n * @param {number} key\n * @return {void}\n */\nMyHashSet.prototype.remove = function(key) {\n    const hash = this.hash(key);\n    \n    if (!this.arr[hash]) {\n        return;\n    } else {\n        let head = this.arr[hash];\n        let node = head;\n        let last; // we\'ll keep track of the previous node for tying the ll back together\n        \n        // find the value\n        while (node) {\n            \n            if (node.val === key) {\n                // if it happened to be head the logic is different\n               if (node === head) {\n                   this.arr[hash] = node.next;\n               } else {\n                   // remove node\n                   last.next = node.next;\n                   node.next = null; // not sure if JS needs this to garbage collect tbh\n                   return;\n               }\n            }\n            \n            last = node;\n            node = node.next;\n        }\n    }\n};\n\n/**\n * Returns true if this set contains the specified element \n * @param {number} key\n * @return {boolean}\n */\nMyHashSet.prototype.contains = function(key) {\n    const hash = this.hash(key);\n    \n    // contains is the easiest of the 3, just find bucket and follow ll\n    if (!this.arr[hash]) {\n        return false;\n    } else {\n        let head = this.arr[hash];\n        let node = head;\n        \n        while (node) {\n            if (node.val === key) {\n                return true;\n            }\n            node = node.next;\n        }\n    }\n    \n    return false;\n};\n\n/** \n * Your MyHashSet object will be instantiated and called as such:\n * var obj = new MyHashSet()\n * obj.add(key)\n * obj.remove(key)\n * var param_3 = obj.contains(key)\n */\n ```
[]