用JavaScript刷leetcode面试题17.09.题-第k个数

361 阅读2分钟

一、题目描述

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

输入: k = 5

输出: 9

更加详细的题目描述请看leetcode链接

二、题目分析

1.素因子只有3,5,7 代表此类数都符合如图的公式,a,b,c大于等于0

image.png
2. 我们维护一个数组,这个数组从小到大存放符合上图公式的数,为方便描述,我们暂且称此类数是合规数
3. 每个合规数,乘3,或5,或7。我们可以通过这个方法的出所有的合规数
4. 数组中的合规数从小到大排列,于是我们可以先初始化这个数组为[1],通过三个指针指向数组的下标0
5. 三个指针每轮计算得到一个最小值,就是下个合规数,加入数组,指针后移一位
6. 三个指针代表合规数应该乘以3、乘以5、乘以7
7. 因为每次像数组中加入的合规数都是最小值,所以可以做到不漏
8. 但是可能会重复,我们通过指针后移,可以做到不重
接下来我们来看下代码

三、代码

git代码链接

/**
 * @param {number} k
 * @return {number}
 */
var getKthMagicNumber = function(k) {
  // 初始化数组
  let arr = [1]
  // 3指针,指向数组下标
  let p3 = 0, p5 = 0, p7 = 0
  // 返回值
  let ret = 1
  // 由于只需要返回第k个合规数,所以我们的迭代继续条件是数组长度小于k
  while(arr.length < k) {
    // 找出最小值
    const v3 = arr[p3] * 3
    const v5 = arr[p5] * 5
    const v7 = arr[p7] * 7
    ret = getMin(v3, v5, v7)
    // 将最小值push进数组
    arr.push(ret)
   
    // 指针后移,为什么不用else if,去重
    if(ret === v3) {
      p3++
    } 
    if(ret === v5) {
      p5++
    }
    if(ret === v7) {
      p7++
    }
  }
  return ret
};

function getMin() {
  return Math.min.apply(null, arguments)
}