leetcode 面试题 17.09. 第 k 个数

面试题 17.09. 第 k 个数

难度中等8

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

示例 1:

输入: k = 5

输出: 9

 

class Solution {
public:
    int getKthMagicNumber(int k) {
        if(k < 1)
            return 0;
        int ary[1000000];
        ary[0] = 1;
        int index3 = 0; int index5 = 0; int index7 = 0;
        for(int i = 1; i < k; i++){
            int num = min(3*ary[index3], min(5*ary[index5], 7 * ary[index7]));            if(num == 3 * ary[index3]) index3++;
            if(num == 5 * ary[index5]) index5++;
            if(num == 7 * ary[index7]) index7++;

            ary[i] = num;
        }
        return ary[k-1];
    }
};

解析:

解答这道题目,首先要分析3,5,7这3个素因子可以产生的从小到大的序列X = {1,3,5,7,9......}。因为3,5,7三个数是素数,也就是互质,所以,这个序列X中的元素不存在重复的可能。然后呢,关键点来了,如何得到这个序列呢?

为了解答这个问题,需要先肯定一个推论,就是序列后面的数 x_j 一定是前面的数 x_i ( i < j),通过乘以几个3,几个5,几个7得到的(这里的几个是大于等于0的意思,不过至少有一个"几个"代表的不是0)。这个推论很显然是正确的。 

如此,我们可以使用前面已经知道的值,计算出后面未知的值。

前面的值,也就是每个已经确定的值,乘以3,5或者7都可以得到一个后面的值,并且,前面的值,例如 第1个到第6个,第1个乘以3的值肯定小于第2个乘以3的值。所以,一旦一个值乘以3乘过了,结果已经放置到最后了,就不需要继续用来乘以3了,想要乘以3得到更大的值,就得用这个数后面的数。同理,5啊,7啊,也是一样。

这样,我们可以为3,5,7分别设置一个指针,指向我们已经得到的(前面的值),并且还没有用来计算未知的(后面的值)。而确定当前位置的值,只需要对3,5,7各自指向的值,并且各自乘以3,5,7后的值取最小,就可以得到目前最小的未知的值。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章