Map blacklisted numbers, create map elegantly in single pass
Intuition\nWe want to only call Math.random() once, we want to be able to check the blacklist once to figure out the actual output to return, and we want to be 
# Intuition\nWe want to only call Math.random() once, we want to be able to check the blacklist once to figure out the actual output to return, and we want to be able to process the blacklist quickly. \n\n# Approach\nAt `pick` time, we generate a random number in the range `[0, n - blacklist.length]` as that reflects the actual number of valid outputs. However, that number may be in the blacklist, so, we refer to a map to figure out what to transform that number into.\n\nTo build that map, we go through the blacklist and assign each blacklisted number to a new map-to value that starts right after `n - blacklist.length` incrementing by one each time.\n\nHowever, the map-to values we assign are not guaranteed to be valid outputs as they may also be in the blacklist. To fix this, everytime we process a blacklisted number, we also need to check if another blacklisted number has already been mapped to it.\n\nBecause of this, we need to process the blacklisted numbers in ascending order. At each blacklisted number, we will be able to determine if it is a brand new number, or if it has already been assigned as a map-to value for another blacklisted number.\n\nFor brand new numbers, we simply assign the next map-to number. For those that have already been referenced, we need to go back and update the entry that referenced it.\n\n# Optimization\nNow, it is possible to avoid sorting with a little bit of acrobatics. Instead of simply tacking on a new tail segment and updating the head entry on each iteration, we make the code a bit complex to handle the possibility of attaching head segments and joining chains.\n\nIt turns out that this can be elegantly done, most of the acrobatics is in determine the head and tail indices.\n\n# Complexity\n- Time complexity:\n- - Solution: $$O(b)$$\n- - Pick: $$O(1)$$\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\n\n- Space complexity:\n- - Solution: $$O(b)$$\n- - Pick: $$O(1)$$\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\n\n# Code\n```\n/**\n * @param {number} n\n * @param {number[]} blacklist\n */\nvar Solution = function(n, blacklist) {\n    this.space = n - blacklist.length;\n    this.map = {};\n\n    blacklist.forEach((b, i) => {\n        const next = this.space + i;\n\n        const head = this.map[b] === undefined ? b : this.map[b];\n        const tail = this.map[next] === undefined ? next : this.map[next];\n\n        this.map[head] = tail;\n        this.map[tail] = head;\n    });\n};\n\n/**\n * @return {number}\n */\nSolution.prototype.pick = function() {\n    const result = Math.floor(Math.random() * this.space);\n    return this.map[result] || result;\n};\n\n/** \n * Your Solution object will be instantiated and called as such:\n * var obj = new Solution(n, blacklist)\n * var param_1 = obj.pick()\n */\n```
['JavaScript']