题目描述
有些数的素因子只有 3,5,7,请设计一个算法找出第 k 个数。注意,不是必须有这些素因子,而是必须不包含其他的素因子。例如,前几个数按顺序应该是 1,3,5,7,9,15,21。
分析
输入:k 表示要找第几个数
输出:找到的数
解题思路
题目告诉我们找到第 k 个因子只有 3,5,7 的数,那实际上就是去从小到大地去找 3,5,7 乘积的组合,我们举几个例子:
比如只有一个 3,5,7。那么是就是 3,5,7;两个 3 就是 9,3 * 5 就是 15。可以看到我们每次都需要找到一个最小的数,放在一个数据结构里,然后再找下一个数,这是要保证顺序必须是递增的,我们才能最终找到第 k 个数。
我们通过观察找规律,可以发现,在找数的过程中,每次都是前一个数字去和 3,5,7 进行乘法运算,我们只会取最小的那个,也就是用 Math.min 去拿到最小的值。
所以我们可以构建这样一个算法,通过3个指针:p3, p5, p7 来分别表示和 3,5,7 来进行相乘的那个数字所在 index,如果本轮和 3 进行了乘法运算,p3 就向前移动一位,对于 5 和 7 也是如此。
OK,主要的计算过程就是这些。还需要注意 ⚠️ 的一点是,我们在计算的过程中,可能会有重复的情况,比如 3 * 5 与 5 * 3,我们可以这样,只要本轮计算完发现 3,5,7 中的某个是本轮计算结果的因子,就直接让他对应的 index 向前走一步,这样就减少了重复~
代码
/**
* @param {number} k
* @return {number}
*/
var getKthMagicNumber = function (k) {
const dp = [1]
let p3 = 0
let p5 = 0
let p7 = 0
for (let i = 1; i < k; i++) {
dp[i] = Math.min(dp[p3] * 3, dp[p5] * 5, dp[p7] * 7)
if (dp[i] === dp[p3] * 3) p3++
if (dp[i] === dp[p5] * 5) p5++
if (dp[i] === dp[p7] * 7)p7++
}
return dp[k - 1]
}
getKthMagicNumber(9)
复杂度
时间:O(N),复杂度与 k 正相关
空间:O(N),存储 k 个数据