313. Super Ugly Number
2016-06-25 11:28
253 查看
题目:
Write a program to find the nth super ugly number.
Super ugly numbers are positive numbers whose all prime factors are in the given prime list
size
Note:
(1)
(2) The given numbers in
(3) 0 <
106, 0 <
1000.
题意:
写一个程序去找到第n个“超级丑数”,超级丑数定义为:
超级丑数是指只包含给定的k个质因子的正数,例如,给定长度为4的质数序列primes = [2, 7, 13, 19],前12个超级丑陋数序列为:[1, 2, 4, 7, 8, 13, 14, 16, 19, 26, 28, 32]
注意:
1、1被认为是超级丑数,无论给定怎样的质数列表。
2、给定的质数列表以升序排列。
3、0 < k ≤ 100, 0 < n ≤ 106, 0 < primes[i] < 1000。
转载地址:https://leetcode.com/discuss/81411/java-three-methods-23ms-58ms-with-heap-performance-explained
思路一:
和 leetcode Ugly Number II 思路一样,要使得super ugly number 不漏掉,那么用每个因子去乘第一个,当前因子乘积是最小后,乘以下一个…..以此类推。
代码:java版:34ms
public class Solution {
public int nthSuperUglyNumber(int n, int[] primes) {
int[] ugly = new int
;
int[] idx = new int[primes.length];
ugly[0] = 1;
for (int i=1; i<n; i++) {
//找到下一个ugly number
ugly[i] = Integer.MAX_VALUE;
for (int j=0; j<primes.length; j++) {
ugly[i] = Math.min(ugly[i], primes[j]*ugly[idx[j]]);
}
//跳过重复值
for (int j=0; j<primes.length; j++) {
while (primes[j] * ugly[idx[j]] <= ugly[i]) idx[j]++;
}
}
return ugly[n-1];
}
}
思路二:
观察上面算法可以看到,依然还是有一部分冗余的乘法可以避免,并且可以将两次循环综合成一次。主要是利用空间换时间。将每一次循环产生的几个丑数都分别保存到数组中。
代码:java版:23ms
public class Solution {
public int nthSuperUglyNumber(int n, int[] primes) {
int[] ugly = new int
;
int[] idx = new int[primes.length];
int[] val = new int[primes.length];
Arrays.fill(val, 1);
int next = 1;
for (int i=0; i<n; i++) {
ugly[i] = next;
next = Integer.MAX_VALUE;
for (int j=0; j<primes.length; j++) {
//跳过重复值以及冗余的乘法操作
if (val[j] == ugly[i]) val[j] = ugly[idx[j]++] * primes[j];
//找到下一个ugly number
next = Math.min(next, val[j]);
}
}
return ugly[n - 1];
}
}
思路三:
理论上可以通过将每一个候选值放到堆中来改善运行的时间复杂度,但是实际上并没有优于以上两种写法,可能是由于java中使用了较高级别的对象而不是最基础的。
代码:java版:60ms
public class Solution {
public int nthSuperUglyNumber(int n, int[] primes) {
int[] ugly = new int
;
PriorityQueue<Num> pq = new PriorityQueue<>();
for (int i = 0; i < primes.length; i++) pq.add(new Num(primes[i], 1, primes[i]));
ugly[0] = 1;
for (int i = 1; i < n; i++) {
ugly[i] = pq.peek().val;
while (pq.peek().val == ugly[i]) {
Num nxt = pq.poll();
pq.add(new Num(nxt.p * ugly[nxt.idx], nxt.idx + 1, nxt.p));
}
}
return ugly[n - 1];
}
private class Num implements Comparable<Num> {
int val;
int idx;
int p;
public Num(int val, int idx, int p) {
this.val = val;
this.idx = idx;
this.p = p;
}
@Override
public int compareTo(Num that) {
return this.val - that.val;
}
}
}
Write a program to find the nth super ugly number.
Super ugly numbers are positive numbers whose all prime factors are in the given prime list
primesof
size
k. For example,
[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]of size 4.
Note:
(1)
1is a super ugly number for any given
primes.
(2) The given numbers in
primesare in ascending order.
(3) 0 <
k≤ 100, 0 <
n≤
106, 0 <
primes[i]<
1000.
题意:
写一个程序去找到第n个“超级丑数”,超级丑数定义为:
超级丑数是指只包含给定的k个质因子的正数,例如,给定长度为4的质数序列primes = [2, 7, 13, 19],前12个超级丑陋数序列为:[1, 2, 4, 7, 8, 13, 14, 16, 19, 26, 28, 32]
注意:
1、1被认为是超级丑数,无论给定怎样的质数列表。
2、给定的质数列表以升序排列。
3、0 < k ≤ 100, 0 < n ≤ 106, 0 < primes[i] < 1000。
转载地址:https://leetcode.com/discuss/81411/java-three-methods-23ms-58ms-with-heap-performance-explained
思路一:
和 leetcode Ugly Number II 思路一样,要使得super ugly number 不漏掉,那么用每个因子去乘第一个,当前因子乘积是最小后,乘以下一个…..以此类推。
代码:java版:34ms
public class Solution {
public int nthSuperUglyNumber(int n, int[] primes) {
int[] ugly = new int
;
int[] idx = new int[primes.length];
ugly[0] = 1;
for (int i=1; i<n; i++) {
//找到下一个ugly number
ugly[i] = Integer.MAX_VALUE;
for (int j=0; j<primes.length; j++) {
ugly[i] = Math.min(ugly[i], primes[j]*ugly[idx[j]]);
}
//跳过重复值
for (int j=0; j<primes.length; j++) {
while (primes[j] * ugly[idx[j]] <= ugly[i]) idx[j]++;
}
}
return ugly[n-1];
}
}
思路二:
观察上面算法可以看到,依然还是有一部分冗余的乘法可以避免,并且可以将两次循环综合成一次。主要是利用空间换时间。将每一次循环产生的几个丑数都分别保存到数组中。
代码:java版:23ms
public class Solution {
public int nthSuperUglyNumber(int n, int[] primes) {
int[] ugly = new int
;
int[] idx = new int[primes.length];
int[] val = new int[primes.length];
Arrays.fill(val, 1);
int next = 1;
for (int i=0; i<n; i++) {
ugly[i] = next;
next = Integer.MAX_VALUE;
for (int j=0; j<primes.length; j++) {
//跳过重复值以及冗余的乘法操作
if (val[j] == ugly[i]) val[j] = ugly[idx[j]++] * primes[j];
//找到下一个ugly number
next = Math.min(next, val[j]);
}
}
return ugly[n - 1];
}
}
思路三:
理论上可以通过将每一个候选值放到堆中来改善运行的时间复杂度,但是实际上并没有优于以上两种写法,可能是由于java中使用了较高级别的对象而不是最基础的。
代码:java版:60ms
public class Solution {
public int nthSuperUglyNumber(int n, int[] primes) {
int[] ugly = new int
;
PriorityQueue<Num> pq = new PriorityQueue<>();
for (int i = 0; i < primes.length; i++) pq.add(new Num(primes[i], 1, primes[i]));
ugly[0] = 1;
for (int i = 1; i < n; i++) {
ugly[i] = pq.peek().val;
while (pq.peek().val == ugly[i]) {
Num nxt = pq.poll();
pq.add(new Num(nxt.p * ugly[nxt.idx], nxt.idx + 1, nxt.p));
}
}
return ugly[n - 1];
}
private class Num implements Comparable<Num> {
int val;
int idx;
int p;
public Num(int val, int idx, int p) {
this.val = val;
this.idx = idx;
this.p = p;
}
@Override
public int compareTo(Num that) {
return this.val - that.val;
}
}
}
相关文章推荐
- 面向对象设计原则之单一职责原则
- Request.UrlReferrer 实现页面刷新
- android http网络编程
- ios代理,多个界面代理问题。
- java开发编译器之:LALR语法解析及代码生成
- iptables清空链的规则
- 第7条:避免使用终结方法
- Mysql5.6.17 zip版本安装
- 欢迎使用CSDN-markdown编辑器
- 浅谈Python中的yield表达式
- javaWeb -- 虚拟主机以及虚拟目录映射的配置
- Net Core
- 使用UE4/Unity创建VR项目
- 使用UE4/Unity创建VR项目
- "alert(1) to win" writeup
- sql练习题2(50题)
- android 简单的广告条实现
- 小代码 小软件
- Linux git安装、升级
- 信息安全技术及应用 公开密钥加密技术