返回
高效算法解题:动态规划巧取丑数II
前端
2023-12-29 10:15:49
在计算机科学领域,丑数被定义为仅由质因数2、3和5组成的正整数。例如,1、2、3、4、5、6、8、9、10都是丑数。
LeetCode 264题要求我们编写一个程序,找出第 n 个丑数。例如,当n=10时,第10个丑数是12。
为了解决这个问题,我们可以使用动态规划算法。动态规划是一种自底向上的解题方法,它将问题分解为更小的子问题,然后逐步解决这些子问题,最终得到问题的整体解决方案。
在LeetCode 264题中,我们可以将丑数序列表示为一个数组。数组的第一个元素是1,然后依次是2、3、4、5、6,依此类推。
为了找到第n个丑数,我们可以使用动态规划算法来填充这个数组。具体步骤如下:
- 初始化数组丑数数组dp,其中dp[0] = 1。
- 创建三个指针i2、i3和i5,分别指向dp数组中2、3和5的倍数的索引。
- 遍历dp数组,从索引1开始,直到索引n。
- 在每次迭代中,比较dp[i2]、dp[i3]和dp[i5]的大小,并选择其中最小的一个。将这个最小值存储在dp[i]中。
- 如果最小值是dp[i2],则将i2增加1,表示下一个2的倍数的索引。
- 如果最小值是dp[i3],则将i3增加1,表示下一个3的倍数的索引。
- 如果最小值是dp[i5],则将i5增加1,表示下一个5的倍数的索引。
重复步骤3到7,直到填充完dp数组。此时,dp[n]就是第n个丑数。
这里有一个使用JavaScript编写的LeetCode 264题的解决方案:
const uglyNumbers = (n) => {
if (n <= 0) {
throw new Error("Invalid input: n must be a positive integer.");
}
const dp = [1];
let i2 = 0;
let i3 = 0;
let i5 = 0;
for (let i = 1; i < n; i++) {
const next2 = dp[i2] * 2;
const next3 = dp[i3] * 3;
const next5 = dp[i5] * 5;
const nextUgly = Math.min(next2, next3, next5);
dp.push(nextUgly);
if (nextUgly === next2) {
i2++;
}
if (nextUgly === next3) {
i3++;
}
if (nextUgly === next5) {
i5++;
}
}
return dp[n - 1];
};
console.log(uglyNumbers(10)); // 12
这个解决方案的时间复杂度为O(n),空间复杂度为O(n)。
希望本文能帮助您理解LeetCode 264题的解题方法。如果您有任何问题,请随时留言。