[路飞] 18——leetcode - 第K个数

173 阅读2分钟

面试题 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*55*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];
};