264. 丑数 II
给你一个整数 n ,请你找出并返回第 n 个 丑数 。
丑数 就是只包含质因数 2、3 和/或 5 的正整数。
示例 1:
输入:n = 10 输出:12 解释:[1, 2, 3, 4, 5, 6, 8, 9, 10, 12] 是由前 10 个丑数组成的序列。
示例 2:
输入:n = 1 输出:1 解释:1 通常被视为丑数。
提示:
- 1 <= n <= 1690
思路:
方法一:使用优先队列 + 集合去重
方法二:使用多路归并,本质上是DP
// 多路归并class Solution {public int nthUglyNumber(int n) {int[] p = new int[n];p[0] = 1;int x = 0, y = 0, z = 0;for (int i = 1; i < n; i++) {int a = p[x] * 2, b = p[y] * 3, c = p[z] * 5;int min = Math.min(a, Math.min(b, c));if (a == min) x++;if (b == min) y++;if (c == min) z++;p[i] = min;}return p[n - 1];}}
313. 超级丑数
超级丑数 是一个正整数,并满足其所有质因数都出现在质数数组 primes 中。
给你一个整数 n 和一个整数数组 primes ,返回第 n 个 超级丑数 。
题目数据保证第 n 个 超级丑数 在 32-bit 带符号整数范围内。
示例 1:
输入:n = 12, primes = [2,7,13,19] 输出:32 解释:给定长度为 4 的质数数组 primes = [2,7,13,19],前 12 个超级丑数序列为:[1,2,4,7,8,13,14,16,19,26,28,32] 。
示例 2:
输入:n = 1, primes = [2,3,5] 输出:1 解释:1 不含质因数,因此它的所有质因数都在质数数组 primes = [2,3,5] 中。
提示:
1 <= n <= 1061 <= primes.length <= 1002 <= primes[i] <= 1000- 题目数据 保证 primes[i] 是一个质数
- primes 中的所有值都 互不相同 ,且按 递增顺序 排列
// 暴力多路归并class Solution {public int nthSuperUglyNumber(int n, int[] primes) {int[] res = new int[n];res[0] = 1;int[] p = new int[primes.length];for (int i = 1; i < n; i++) {int min = Integer.MAX_VALUE;for (int j = 0; j < p.length; j++) {if (res[p[j]] * primes[j] < min)min = res[p[j]] * primes[j];}res[i] = min;for (int j = 0; j < p.length; j++)if (res[p[j]] * primes[j] == min)p[j]++;}return res[n - 1];}}
// 堆优化的多路归并class Solution {public int nthSuperUglyNumber(int n, int[] primes) {PriorityQueue<int[]> q = new PriorityQueue<>((o1, o2) -> (o1[0] - o2[0]));for (int i = 0; i < primes.length; i++) {q.offer(new int[]{primes[i], i, 1});}int[] res = new int[n];res[0] = 1;for (int i = 1; i < n;) {int[] p = q.poll();if (p[0] != res[i - 1]) res[i++] = p[0];q.offer(new int[]{res[p[2]] * primes[p[1]], p[1], p[2] + 1});}return res[n - 1];}}
986. 区间列表的交集
二路归并
