[路飞]_算法成长之路十九,第 k 个数

105 阅读2分钟

个人算法成长之路十九!!!定期更新一些刷题过程中个人的思路以及理解。有兴趣的朋友们可以互动交流哈~

题目:

leetcode-面试题 17.09. 第 k 个数

有些数的素因子只有 3,5,7,请设计一个算法找出第 k 个数。注意,不是必须有这些素因子,而是必须不包含其他的素因子。例如,前几个数按顺序应该是 1,3,5,7,9,15,21。 示例 1:

输入: k = 5

输出: 9

解题思路:

按照题意这个数必然可以拆解成 3^n * 5^m * 7^l , 记录 m ,l ,n的最大值 , 下一个仍然是可以拆分出新的 m ,l, n; m, l, n就代表, 对应因子出现的次数 所以下一个数,也能表示为之前的数 乘 3 或 5 或 7 。 从1 开始,下一个数字就在 1 * 3, 1 * 5, 1 * 7 这三个数字里选, 这样3就出现过一次了,如果下一次还出现 3这个因子,肯定不可能还是与1相乘, 只能与下一位3 相乘, 而 5 7 还是与 1相乘 因为还没出现过。 因子出现一次,对应的记号就+1。

/**
 * @param {number} k
 * @return {number}
 */
 /* 升序的第k个数
 可用最小堆 
 但是固定因子是什么鬼,
 错了这个是一个函数f(n)求通项公式呢
f(n)和f(n+1)的关系,  不太好找。
按照题意这个数必然可以拆解成 3^n * 5^m * 7^l
记录 m l n , 下一个数必然是 m l n 其中有个数+1


 */
var getKthMagicNumber = function(k) {
    /* k3, k5, k7 分别代表 3 5 7 因子在之前的数里面出现的最多的次数
    也就是该因子 已经出现了多少次
    当前数如果 是之前的某个数乘以该因子 则该因子的指针进一
     */
    let [k3,k5,k7]= [0,0,0], fn = [1];

    while(fn.length < k){
        // let next = Math.pow(3,k3)* Math.pow(5, k5)*Math.pow() * 3;
        let next = fn[k3]* 3 ;
        next  = Math.min(next,fn[k5]* 5 )
        next  = Math.min(next,fn[k7]* 7 )
        if(fn[k3] * 3 === next){ k3++}
        if(fn[k5] * 5 === next){ k5++}
        if(fn[k7] * 7 === next){ k7++}
        fn.push(next)
    }
    return fn[k-1]
};