持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
题目描述
有些数的素因子只有 3,5,7,请设计一个算法找出第 k 个数。注意,不是必须有这些素因子,而是必须不包含其他的素因子。例如,前几个数按顺序应该是 1,3,5,7,9,15,21。
示例 1:
输入: k = 5
输出: 9
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/get-kth-magic-number-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路分析
- 今天的算法题目是求第 k 个数, 根据题目描述, 数值的计算算法是素因子只有 3,5,7。而且我们需要对计算出的数值进行从小到大的排序。 理解了题意之后,我们可以按照计算规则,计算数据,然后将所有的计算结果进行去重存储排序。
- 对于数据去重,我们一般使用 Set 数据结构,可以保持容器中的元素不重复。Java中常见的实现有HashSet(随机位置插入的 Set),LinkedHashSet( 保持插入顺序的 Set)。TreeSet(保持容器中元素有序的 Set,默认为升序)。可以按照需要取用。
- 由于数据需要从小到大排序,我们一般使用heap堆来实现。堆是一棵树,其每个节点都有一个键值,且每个节点的键值都大于等于/小于等于其父亲的键值。 我们这个题目使用小根堆,方便获取每次的最小值。
- 选定好了数据结构,按照题目,具体实现代码如下,供参考。
通过代码
public int getKthMagicNumber(int k) {
int[] factors = new int[]{3, 5, 7};
Set<Long> set = new HashSet<Long>();
PriorityQueue<Long> heap = new PriorityQueue<Long>();
set.add(1L);
heap.offer(1L);
int ans = 0;
for (int i = 0; i < k; i++) {
long curr = heap.poll();
ans = (int) curr;
for (int factor : factors) {
long next = curr * factor;
if (set.add(next)) {
heap.offer(next);
}
}
}
return ans;
}
总结
- 上述算法的时间复杂度是O(log n), 空间复杂度是O(n)
- 坚持算法每日一题,加油!