第 k 个数
难度:
标签:
题目描述
Design an algorithm to find the kth number such that the only prime factors are 3, 5, and 7. Note that 3, 5, and 7 do not have to be factors, but it should not have any other prime factors. For example, the first several multiples would be (in order) 1, 3, 5, 7, 9, 15, 21.
Example 1:
Input: k = 5 Output: 9
代码结果
运行时间: 24 ms, 内存: 16.6 MB
/*
* 题目思路:
* 使用Java Stream API同样需要实现最小堆和去重机制。
* 由于Stream不直接支持优先队列,我们仍然需要结合使用PriorityQueue和HashSet。
*/
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.stream.Stream;
public class KthNumberWithPrimeFactorsStream {
public int getKthMagicNumber(int k) {
if (k <= 0) return 0;
PriorityQueue<Long> minHeap = new PriorityQueue<>();
HashSet<Long> seen = new HashSet<>();
long[] primes = {3, 5, 7};
minHeap.add(1L);
seen.add(1L);
long number = 1;
for (int i = 0; i < k; i++) {
number = minHeap.poll();
for (long prime : primes) {
long newNumber = number * prime;
if (!seen.contains(newNumber)) {
seen.add(newNumber);
minHeap.add(newNumber);
}
}
}
return (int) number;
}
public static void main(String[] args) {
KthNumberWithPrimeFactorsStream solution = new KthNumberWithPrimeFactorsStream();
System.out.println(solution.getKthMagicNumber(5)); // 输出: 9
}
}
解释
方法:
该题解使用了最小堆(优先队列)以及哈希集合来求解。首先,1被视为第一个满足条件的数,因此初始化堆和集合都包含这个数。对于每次从堆中弹出的最小数(当前的最小数),将它与3、5、7分别相乘,得到的新数如果之前未出现过,就加入到堆和集合中。这个过程重复k次,最后从堆中弹出的数即为第k个数。
时间复杂度:
O(k log k)
空间复杂度:
O(k)
代码细节讲解
🦆
为什么选择使用最小堆(优先队列)而不是其他数据结构如数组或链表来解决这个问题?
▷🦆
在处理生成的新数时,使用哈希集合来检查元素是否已出现。这种方法的效率如何,是否有可能成为性能瓶颈?
▷🦆
题解中提到每次操作都会插入最多三个元素,但堆的最大大小为什么是3k而不是k或更大?
▷