難度中等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後的值取最小,就可以得到目前最小的未知的值。