【LeetCode】第 k 个数 Java 题解

64 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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)
  • 坚持算法每日一题,加油!