面试题 17.09. 第 k 个数
题目
有些数的素因子只有 3,5,7,请设计一个算法找出第 k 个数。注意,不是必须有这些素因子,而是必须不包含其他的素因子。例如,前几个数按顺序应该是 1,3,5,7,9,15,21。
示例:
// k不一定是5,取决于k取值多少,需要把后面的值都算出来
输入:k = 5
输出: 9
思路
这个题要求找出,除了这个数的本身之外,3、5、7的倍数,这个区间内的数字是由3^a * 5^b * 7^c.
- 设计一个算法,找出第k个数,先要把3的倍数,5的倍数,7的倍数都找到,并从小到大排序
- 找到第k个数,第k个数就是在最终的结果中找下标为k-1的值。
注意: 需要考虑去重的问题,比如3*5和5*3是一样的结果,就需要去重。如果两个素因子相乘算出来相同的结果,就让当前素因子被使用的次数加1.
算法
/**
* @param {number} k
* @return {number}
*/
var getKthMagicNumber = function(k) {
var p3 = 0; // 3出现的次数
var p5 = 0; // 5出现的次数
var p7 = 0; // 7出现的次数
var dp = new Array(k); // 存放结果
dp[0] = 1;
// 求3的倍数 5的倍数 7的倍数的最小值
for (let i = 1; i < k; i++) {
dp[i] = Math.min(dp[p3] * 3, Math.min(dp[p5] * 5, dp[p7] * 7)); // 找的是3个素因子相乘的出来的结果。
// 去重操作:dp中的每一个元素跟素因子3和它所出现的次数来进行比较,比如3*5 = 5*3, 3*7 = 7*3, 5*7 = 7*5
if (dp[i] === dp[p3] * 3) p3++; // 对3去重
if (dp[i] === dp[p5] * 5) p5++; // 对5去重
if (dp[i] === dp[p7] * 7) p7++; // 对7去重
}
return dp[k - 1];
};