zoukankan      html  css  js  c++  java
  • [LeetCode] 313. Super Ugly Number

    A super ugly number is a positive integer whose prime factors are in the array primes.

    Given an integer n and an array of integers primes, return the nth super ugly number.

    The nth super ugly number is guaranteed to fit in a 32-bit signed integer.

    Example 1:

    Input: n = 12, primes = [2,7,13,19]
    Output: 32
    Explanation: [1,2,4,7,8,13,14,16,19,26,28,32] is the sequence of the first 12 super ugly numbers given primes = [2,7,13,19].
    

    Example 2:

    Input: n = 1, primes = [2,3,5]
    Output: 1
    Explanation: 1 has no prime factors, therefore all of its prime factors are in the array primes = [2,3,5].

    Constraints:

    • 1 <= n <= 106
    • 1 <= primes.length <= 100
    • 2 <= primes[i] <= 1000
    • primes[i] is guaranteed to be a prime number.
    • All the values of primes are unique and sorted in ascending order.

    超级丑数。

    超级丑数 是一个正整数,并满足其所有质因数都出现在质数数组 primes 中。

    给你一个整数 n 和一个整数数组 primes ,返回第 n 个 超级丑数 。

    题目数据保证第 n 个 超级丑数 在 32-bit 带符号整数范围内。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/super-ugly-number
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    由于题意定义了超级丑数是由给定的 primes 数组生成的,而最小的超级丑数是 1,所以我们需要一个最小堆,首先把 1 放进去。其余的丑数都是由最小堆堆顶的数字 * primes数组里的每一个数字产生而来的。同时我们从最小堆中不断弹出元素,直到我们弹出第 N 个元素位置。这道题会想到这样做不太难,但是朴素的优先队列的做法速度很慢。

    时间:令 [公式] 长度为 [公式],需要从优先队列(堆)中弹出 [公式] 个元素,每次弹出最多需要放入 [公式] 个元素,堆中最多有 [公式] 个元素。复杂度为 [公式]

    空间:[公式]

    Java实现

     1 class Solution {
     2     public int nthSuperUglyNumber(int n, int[] primes) {
     3         HashSet<Long> set = new HashSet<>();
     4         PriorityQueue<Long> heap = new PriorityQueue<>();
     5         set.add(1L);
     6         heap.offer(1L);
     7         int ugly = 0;
     8         for (int i = 0; i < n; i++) {
     9             long cur = heap.poll();
    10             ugly = (int) cur;
    11             for (int p : primes) {
    12                 long next = cur * p;
    13                 if (set.add(next)) {
    14                     heap.offer(next);
    15                 }
    16             }
    17         }
    18         return ugly;
    19     }
    20 }

    比较优化的思路是多路归并,还是会用到最小堆。这里我参考了这个帖子。这个思路优化的重点在于他用了多路归并,这样对于 primes 数组里的每一个数字 primes[i],我们都去试图模拟一个由 primes[i] 生成的丑数的序列,然后每个序列都给一个指针,我们每次只把全局最小的那个丑数放入最小堆。但是从实际做法来看,我们不需要真的创建那么多丑数序列,这个部分可以通过往最小堆中放入的元素来记录。

    时间:需要构造长度为 [公式] 的答案,每次构造需要往堆中取出和放入元素,堆中有 [公式] 个元素,起始时,需要对 [公式] 进行遍历,复杂度为 [公式]。整体复杂度为 [公式]

    空间:存储 [公式] 个答案,堆中有 [公式] 个元素,复杂度为 [公式]

    Java实现

     1 class Solution {
     2     public int nthSuperUglyNumber(int n, int[] primes) {
     3         int len = primes.length;
     4         PriorityQueue<int[]> queue = new PriorityQueue<>((a, b) -> a[0] - b[0]);
     5         for (int i = 0; i < len; i++) {
     6             queue.offer(new int[] { primes[i], i, 0 });
     7         }
     8 
     9         int[] res = new int[n];
    10         res[0] = 1;
    11         for (int j = 1; j < n;) {
    12             int[] cur = queue.poll();
    13             int val = cur[0];
    14             int i = cur[1];
    15             int idx = cur[2];
    16             if (val != res[j - 1]) {
    17                 res[j++] = val;
    18             }
    19             queue.offer(new int[] { res[idx + 1] * primes[i], i, idx + 1 });
    20         }
    21         return res[n - 1];
    22     }
    23 }

    LeetCode 题目总结

  • 相关阅读:
    FZU.Software Engineering1816 ·The Second Assignment of the Team
    18软工实践-第五次作业-结对作业2
    福大软工1816 · 第四次作业
    软件工程实践第三次作业——结对作业(一)
    软工第二次作业——个人项目
    福大软工1816 · 团队现场编程实战(抽奖系统)
    Alpha 冲刺 (3/10)
    Alpha 冲刺 (2/10)
    Alpha 冲刺 (1/10)
    福大软工 · 第七次作业
  • 原文地址:https://www.cnblogs.com/cnoodle/p/15121279.html
Copyright © 2011-2022 走看看