剑指offer(33)丑数
题目描述
把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
题目分析
主要在于理解丑数的概念,只包含因子2、3和5的数称作丑数,那么我们可以先把因子2、3和5分离出来,那么剩下的就是其他因子,看是否为1,为1的话说明没有其他因子,那就为丑数。不是1的话说明有其他因子,那么就不是丑数。
第一种暴力解法,缺点是连非丑数的也计算力,会超时。
第二种用到了动态规划的思想,把前面的丑数存着,生成后面的丑数。t2,t3,t5是判断点,用于判断从何处开始选出并乘以对应因子肯定会大于当前数组中最大丑数,而前面的丑数不用考虑。
代码
第一种(超时)
function GetUglyNumber_Solution(index) { if (index <= 1) return 0; let count = 0; let num = 0; while (count < index) { num++; if (isUgly(num)) { count++; } } return num; } function isUgly(num) { while (num % 2 === 0) num /= 2; while (num % 3 === 0) num /= 3; while (num % 5 === 0) num /= 5; return num === 1; }
第二种:(以空间换时间)
function GetUglyNumberSolution(index) { if (index < 7) return index; const res = []; res[0] = 1; let t2 = 0, t3 = 0, t5 = 0; for (let i = 1; i < index; i++) { res[i] = Math.min(res[t2] * 2, res[t3] * 3, res[t5] * 5); if (res[i] === res[t2] * 2) t2++; if (res[i] === res[t3] * 3) t3++; if (res[i] === res[t5] * 5) t5++; } return res[index - 1]; }