[路飞]_程序员必刷力扣题: 面试题 17.09. 第 k 个数

258 阅读2分钟

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

面试题 17.09. 第 k 个数

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

 

示例 1:

输入: k = 5

输出: 9

提示:

  • 1 <= t <= 109
  • 保证每次对 ping 调用所使用的 t 值都 严格递增
  • 至多调用 ping 方法 104 次

数组

思路

我们通过题干来寻找规律,可以发现, 其实就是将,数的每个位置的值分别* 3 /* 5 /* 7 ,最后将这些进行大小排序即可

这里我们声明一个dp数组来保存数,跟据上述可以得到三个数列

  1. dp[0] * 3,dp[1] * 3,dp[2] * 3,dp[3] * 3,dp[4] * 3...
  2. dp[0] * 5,dp[1] * 5,dp[2] * 5,dp[3] * 5,dp[4] * 5...
  3. dp[0] * 7,dp[1] * 7,dp[2] * 7,dp[3] * 7,dp[4] * 7... 最后将这三个数列去重合并形成新的,更长的,满足条件的数列

所以这里我们用三指针,分别指向三个数列,然后每次取三个数列的最小值,然后将当前被取的值的指针往后加一位,这样也排除掉了重复的值

因为第k个值是从1开始计算,那么在dp数组中对应的下标会小1

所以返回dp[k-1]位即可

复杂度分析

这里我们只用了一次遍历,所以时间复杂度复杂度是O(n),这里n表示k的大小 这里我们声明了一个dp数组,每向前一步保存一位数,所以空间复杂度也为O(n)这里n表示k的大小

var getKthMagicNumber = function (k) {
    //三指针
    var p3 = 0,p5 = 0,p7 = 0;
    var dp = [1]
    //遍历字符串
    for(var i = 1;i < k ;i++){
        //取最小值
        dp[i] = Math.min(dp[p3]*3,dp[p5]*5,dp[p7]*7)
        if(dp[i]===dp[p3]*3) p3++
        if(dp[i]===dp[p5]*5) p5++
        if(dp[i]===dp[p7]*7) p7++
    }

    return dp[k-1]
}