刷题的日常-第 k 个数

60 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情

刷题的日常-2022年9月28日

一天一题,保持脑子清爽

第 k 个数

来自leetcode的 面试题 17.09 题,题意如下:

有些数的素因子只有 3,5,7,请设计一个算法找出第 k 个数。注意,不是必须有这些素因子,而是必须不包含其他的素因子。例如,前几个数按顺序应该是 1,3,5,7,9,15,21。

示例如下:

输入: k = 5

输出: 9

理解题意

我们可以从题意中提取的条件如下:

  • 题目给出一个数
  • 这个数代表的是第几个素因子
  • 素因子代表的是只有 3 5 7 这三个数的乘积组成
  • 我们要枚举到给定位置的数值并返回

做题思路

从题意我们可以想到其实下一个数的组成必然是前面的数乘以{3,5,7}这三个数组成的新数,所以其实我们可以在前面的基础上进行迭代,但是需要注意的是有可能会出现重复的情况。将过程整理如下:

  • 开辟一个优先级队列,排序规则是从小到大的顺序
  • 为了去重,还需要开辟一个Set集合对已出现的数据进行去重
  • 然后将{3,5,7}作为常量
  • 循环k次
    • 每次取出队列中的最小数,记录到返回值
    • 循环常量
    • 将取出的数 和 常量相乘
    • 如果没有出现过,那么就可以把它加到队列中
    • 如果出现过,直接跳过
    • 因为每次至少会有一个新的值出现,所以这里不需要判空
  • 最终返回结果即可

代码实现

代码实现如下:

public class Solution {

    public int getKthMagicNumber(int k) {
        int[] nums = {3, 5, 7};
        Queue<Long> queue = new PriorityQueue<>();
        Set<Long> set = new HashSet<>();
        long result = 1;
        queue.add(1L);
        set.add(1L);
        for (int i = 0; i < k; i++) {
            result = queue.poll();
            for (int num : nums) {
                if (!set.add(result * num)) {
                    continue;
                }
                queue.add(result * num);
            }
        }
        return (int) result;
    }
}

image.png