题目
(1)有些数的素因子只有 3,5,7,请设计一个算法找出第 k 个素因子。注意,不是必须有这些素因子,而是必须不包含其他的素因子。例如,前几个数按顺序应该是 1,3,5,7,9,15,21。
(2)示例如下所示:
输入: k = 5
输出: 9
解决思路
- 使用队列进行解决,初始化队列的第一个节点的值为1。
- 使用3个指针p3、p5、p7计算下一个数,初始时刻,p3、p5、p7都指向队列的第一个节点。
- 每一轮计算过程中,p3指向的节点的值乘以3,p5指向的节点的值乘以5,p7指向的节点的值乘以7。
- 选择上述每一轮计算出的最小值压入队列,并将最小值对应的指针向后移动一位。
- 注意:当在某一轮计算中,有多个指针对应计算出的值相等且都是最小值时,只向队列中压入一个值,但最小值对应的所有指针都要向后移动一位。
- 上述过程如下图所示:
代码
- C++代码
# include <stdio.h>
# include <vector>
# include <algorithm>
using namespace std;
class Solution {
public:
int getKthMagicNumber(int k) {
vector <int> arr; // 使用数组实现队列
arr.push_back(1); // 初始化队列的头节点为1
int p3 = 0;
int p5 = 0;
int p7 = 0;
while (arr.size() < k) {
int ret = arr[p3] * 3;
ret = min(ret, arr[p5] * 5);
ret = min(ret, arr[p7] * 7);
// 注意不能写成else if,因为存在某轮计算中,多个指针对应的值同时为最小值,
// 写成else if时只会移动一个指针,但应该移动多个指针,所以不能写成else if
if (ret == arr[p3] * 3) {
p3++;
}
if (ret == arr[p5] * 5) {
p5++;
}
if (ret == arr[p7] * 7) {
p7++;
}
arr.push_back(ret);
}
return arr[k - 1];
}
};
int main() {
Solution *solution = new Solution();
int k = 5;
printf("%d", solution->getKthMagicNumber(k));
return 0;
}
- Python代码
# -*- coding: utf-8 -*-
class Solution:
def getKthMagicNumber(self, k: int) -> int:
arr = list() # 使用数组实现队列
arr.append(1) # 初始化队列的头节点为1
p3, p5, p7 = 0, 0, 0
# 注意不能写成elif,因为存在某轮计算中,多个指针对应的值同时为最小值,
# 写成elif时只会移动一个指针,但应该移动多个指针,所以不能写成elif
while len(arr) < k:
ret: int = 3 * arr[p3]
ret = min(ret, 5 * arr[p5])
ret = min(ret, 7 * arr[p7])
if ret == 3 * arr[p3]:
p3 += 1
if ret == 5 * arr[p5]:
p5 += 1
if ret == 7 * arr[p7]:
p7 += 1
arr.append(ret)
return arr[k - 1]
def main():
k: int = 5
print(Solution().getKthMagicNumber(k))
if __name__ == "__main__":
main()
说明
- 对应LeetCode第17.09题。
- 链接:https://leetcode-cn.com/problems/get-kth-magic-number-lcci/