Heavily commented JavaScript bottom up DP solution
\n/**\n * @param {number} n\n * @return {number}\n */\nvar nthUglyNumber = function(n) {\n    \n    if (!n) {\n        return 0;\n    }\n    \n    // General id
```\n/**\n * @param {number} n\n * @return {number}\n */\nvar nthUglyNumber = function(n) {\n    \n    if (!n) {\n        return 0;\n    }\n    \n    // General idea is to build up an array with ugly numbers till we reach n-1\n    // So we will iterate multiples of 2,3,5 and record them.\n    // But, if just store 2,3,5 - 4,6,10 - 6,9,15 etc we\'d be going out of order\n    // So we need to increase the indeces for 2,3,5 more wisely.\n    \n    let i2 = 0, i3 = 0, i5 = 0; // the 2,3,5 indeces\n    let out = [1]; // we will fill this with the ugly multiples\n    \n    while (!out[n-1]) { \n        let c2 = out[i2] * 2;\n        let c3 = out[i3] * 3;\n        let c5 = out[i5] * 5;\n        // In c2,c3,c5 we now have 3 candidates for the next number. Pick the lowest one, to record in order\n        // In the first round that will be 2\n        let next = Math.min(Math.min(c2, c3), c5);\n        out.push(next);\n        \n        if (next === c2) {\n            // now the 2 index will increase, and next round, c2 will be four, so c3=3 will be lowest\n            i2++;\n        }\n        if (next === c3) {\n            i3++;\n        }\n        if (next === c5) {\n            i5++;\n        } \n        \n    }\n\n    return out[n-1]; \n};\n```
['Dynamic Programming', 'JavaScript']