[路飞]_每天刷leetcode_13(第K个数 get-kth-magic-number-lcci)

185 阅读2分钟

这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战

第K个数

LeetCode传送门 面试题 17.09. 第 k 个数

题目

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

Design an algorithm to find the kth number such that the only prime factors are 3, 5, and 7. Note that 3, 5, and 7 do not have to be factors, but it should not have any other prime factors. For example, the first several multiples would be (in order) 1, 3, 5, 7, 9, 15, 21.

Example 1:

Input: k = 5

Output: 9


思考线


解题思路

这道题是关于找到第几个数字的问题,我们可以用动态规划来解决这个问题。关于动态规划问题我们有以下三步

动态规划的基本步骤为

  1. 找到“状态”和“选择”
  2. 明确dp数组/函数的定义
  3. 寻找“状态”之间的关系

那么带入本题我们:

  1. 找到他的状态和转移 每个新的因子都是之前因子 *3 || *5 || *7;
  2. 找出dp数组 由于第一个因子是1,我们后面所有的因子都要通过它推出来,我们的 base case 也就是第一个数 1,所以我们设 dp = [1];
  3. 找到转移函数 由于我们得出每个新的因子都是之前的因子 *3 || *5 || *7, 而之前的因子和题目给定的3、5、7因子所产生的数是递增的。 我们可以设置三个变量(a、b、c)来表示之前因子的dp下标,从而来维护之前因子*3、*5、*7所产生的结果。我们默认其值都为0,然后依次找出和对应变量所维护的因子的值。然后获取其最小值push到dp数组尾部,然后让对应最小值的变量(a||b||c)++, 从而完成一次dp元素的添加。 所以我们很容易得到我们的动态递推公式: dp[i] = Math(dp[a]*3,dp[b]*5,dp[c]*7);
  4. 最后根据关系我们找到dp数组的第k个元素即可。
/**
 * @param {number} k
 * @return {number}
 */
var getKthMagicNumber = function(k) {
   'use strict'
   const dp = [1];
   let a =0, b = 0, c = 0;
   while(dp.length < k) {
       const min = Math.min(dp[a]*3, dp[b]*5, dp[c]*7)
       if(dp[dp.length -1] !== min)dp.push(min);
       switch(min) {
           case dp[a]*3:
                a++;
                break;
            case dp[b]*5:
                b++;
                break; 
            case dp[c]*7:
                c++;
                break; 
       }
   }
   return dp[dp.length -1]

};