[LeetCode] 313. Super Ugly Number 超级丑陋数
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 primes
of size k
.
Example:
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 givenprimes
=[2,7,13,19]
of size 4.
Note:
1
is a super ugly number for any givenprimes
.- The given numbers in
primes
are in ascending order. - 0 <
k
≤ 100, 0 <n
≤ 106, 0 <primes[i]
< 1000. - The nth super ugly number is guaranteed to fit in a 32-bit signed integer.
264. Ugly Number II 的拓展,还是找出第n个丑陋数,但质数集合不在只是2,3,5,而是可以任意给定。难度增加了,但本质上和Ugly Number II 没有什么区别,由于不知道质数的个数,可以用一个idx数组来保存当前的位置,然后从每个子链中取出一个数,找出其中最小值,然后更新idx数组对应位置,注意有可能最小值不止一个,要更新所有最小值的位置。
解题思路:
要使得super ugly number不漏掉,那么需要使用每个因子去乘以其对应的“第一个”丑数。那么何为对应的“第一个”丑数?
首先,利用ugly[]数组来保存所有的超级丑数,ugly[i]表示第i+1个超级丑数;
接着利用pointer[]数组来表示每个因子对应的“第一个”丑数的下标。pointer数组长度当然需要和primes长度一致,且初始化为0,代表着每个因子对应的“第一个”丑数都是ugly[0];
接下来我们以primes[2,7,13,19],pointer[0,0,0,0],ugly[0]=1作为初始条件往下看:
遍历primes数组,用每个因子都乘以其对应的第一个丑数,即ugly[0]=1,可以发现1x2=2是最小值,故ugly[1]=2;但要注意,此时的pointer数组发生了变化:
由于当前产生的丑数2是由2这个因子乘以它的对应“第一个”丑数得到的,因此需要将pointer[0]加一。pointer[0]是2这个因子对应的“第一个”丑数的下标,因为当前已经使用了2x1,如果不更新,则下一轮还是会用2这个因子去乘以第一个丑数(ugly[0]).将其更新后,则意味着2这个因子对应的第一个丑数已经改变了,变成了ugly[1].而其他三个对应的“第一个”丑数还是ugly[0]。
我们接着看下一轮:2x2【即ugly[pointer[1]]x2】,1x7,1x13,1x19,发现还是2这个因子得到的数最小,故更新:ugly[2]=2x2=4,pointer[0]=2;
下一轮:4x2,1x7,1x13,1x19,可以发现当前这一轮最小值是7,且由因子7产生,故更新:ugly[3]=7,pointer[1]=1;
以此类推....
如果更新过程中,出现最小值不止一个的话,则其对应的pointer的值都需要增加1。
Java:
public int nthSuperUglyNumber(int n, int[] primes) {
int[] ugly = new int[n+1];
ugly[0]=1;
int[] pointer = new int[primes.length];
for(int i=1;i<n;i++) {
int min=Integer.MAX_VALUE;
int minIndex = 0;
for(int j=0;j<primes.length;j++) {
if(ugly[pointer[j]]*primes[j]<min) {
min=ugly[pointer[j]]*primes[j];
minIndex = j;
}else if(ugly[pointer[j]]*primes[j]==min) {
pointer[j]++;
}
}
ugly[i]=min;
pointer[minIndex]++;
}
return ugly[n-1];
}
Java:1
public int nthSuperUglyNumberI(int n, int[] primes) {
int[] ugly = new int[n];
int[] idx = new int[primes.length]; ugly[0] = 1;
for (int i = 1; i < n; i++) {
//find next
ugly[i] = Integer.MAX_VALUE;
for (int j = 0; j < primes.length; j++)
ugly[i] = Math.min(ugly[i], primes[j] * ugly[idx[j]]); //slip duplicate
for (int j = 0; j < primes.length; j++) {
while (primes[j] * ugly[idx[j]] <= ugly[i]) idx[j]++;
}
} return ugly[n - 1];
}
Java:2
public int nthSuperUglyNumber(int n, int[] primes) {
int[] ugly = new int[n];
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++) {
//skip duplicate and avoid extra multiplication
if (val[j] == ugly[i]) val[j] = ugly[idx[j]++] * primes[j];
//find next ugly number
next = Math.min(next, val[j]);
}
} return ugly[n - 1];
}
Java: 3 index heap
public int nthSuperUglyNumberHeap(int n, int[] primes) {
int[] ugly = new int[n]; 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;
}
}
Python:
def nthSuperUglyNumber(self, n, primes):
ugly = [1]
pointers = [0]*len(primes) for i in range(1,n):
minu = float("inf")
minIndex = 0
for j in range(len(primes)):
if primes[j] * ugly[pointers[j]] < minu:
minu = primes[j] * ugly[pointers[j]]
minIndex = j
elif primes[j] * ugly[pointers[j]] == minu:
pointers[j] += 1
ugly.append(minu)
pointers[minIndex] += 1
return ugly[-1]
Python:
# Heap solution. (620ms)
class Solution(object):
def nthSuperUglyNumber(self, n, primes):
"""
:type n: int
:type primes: List[int]
:rtype: int
"""
heap, uglies, idx, ugly_by_last_prime = [], [0] * n, [0] * len(primes), [0] * n
uglies[0] = 1 for k, p in enumerate(primes):
heapq.heappush(heap, (p, k)) for i in xrange(1, n):
uglies[i], k = heapq.heappop(heap)
ugly_by_last_prime[i] = k
idx[k] += 1
while ugly_by_last_prime[idx[k]] > k:
idx[k] += 1
heapq.heappush(heap, (primes[k] * uglies[idx[k]], k)) return uglies[-1]
Python:
# Time: O(n * k)
# Space: O(n + k)
# Hash solution. (932ms)
class Solution2(object):
def nthSuperUglyNumber(self, n, primes):
"""
:type n: int
:type primes: List[int]
:rtype: int
"""
uglies, idx, heap, ugly_set = [0] * n, [0] * len(primes), [], set([1])
uglies[0] = 1 for k, p in enumerate(primes):
heapq.heappush(heap, (p, k))
ugly_set.add(p) for i in xrange(1, n):
uglies[i], k = heapq.heappop(heap)
while (primes[k] * uglies[idx[k]]) in ugly_set:
idx[k] += 1
heapq.heappush(heap, (primes[k] * uglies[idx[k]], k))
ugly_set.add(primes[k] * uglies[idx[k]]) return uglies[-1]
Python:
# Time: O(n * logk) ~ O(n * klogk)
# Space: O(n + k)
class Solution3(object):
def nthSuperUglyNumber(self, n, primes):
"""
:type n: int
:type primes: List[int]
:rtype: int
"""
uglies, idx, heap = [1], [0] * len(primes), []
for k, p in enumerate(primes):
heapq.heappush(heap, (p, k)) for i in xrange(1, n):
min_val, k = heap[0]
uglies += [min_val] while heap[0][0] == min_val: # worst time: O(klogk)
min_val, k = heapq.heappop(heap)
idx[k] += 1
heapq.heappush(heap, (primes[k] * uglies[idx[k]], k)) return uglies[-1]
C++:
class Solution {
public:
int nthSuperUglyNumber(int n, vector<int>& primes) {
vector<int> res(1, 1), idx(primes.size(), 0);
while (res.size() < n) {
vector<int> tmp;
int mn = INT_MAX;
for (int i = 0; i < primes.size(); ++i) {
tmp.push_back(res[idx[i]] * primes[i]);
}
for (int i = 0; i < primes.size(); ++i) {
mn = min(mn, tmp[i]);
}
for (int i = 0; i < primes.size(); ++i) {
if (mn == tmp[i]) ++idx[i];
}
res.push_back(mn);
}
return res.back();
}
};
C++:
class Solution {
public:
int nthSuperUglyNumber(int n, vector<int>& primes) {
vector<int> dp(n, 1), idx(primes.size(), 0);
for (int i = 1; i < n; ++i) {
dp[i] = INT_MAX;
for (int j = 0; j < primes.size(); ++j) {
dp[i] = min(dp[i], dp[idx[j]] * primes[j]);
}
for (int j = 0; j < primes.size(); ++j) {
if (dp[i] == dp[idx[j]] * primes[j]) {
++idx[j];
}
}
}
return dp.back();
}
};
类似题目:
[LeetCode] 263. Ugly Number 丑陋数
[LeetCode] 264. Ugly Number II 丑陋数 II
All LeetCode Questions List 题目汇总
[LeetCode] 313. Super Ugly Number 超级丑陋数的更多相关文章
- [LeetCode]313. Super Ugly Number超级丑数,丑数系列看这一道就行了
丑数系列的题看这一道就可以了 /* 和ugly number2差不多,不过这次的质因子多了,所以用数组来表示质因子的target坐标 target坐标指的是这个质因子此次要乘的前任丑数是谁 */ pu ...
- [LeetCode] Super Ugly Number 超级丑陋数
Write a program to find the nth super ugly number. Super ugly numbers are positive numbers whose all ...
- [LintCode] Super Ugly Number 超级丑陋数
Write a program to find the nth super ugly number. Super ugly numbers are positive numbers whose all ...
- 313 Super Ugly Number 超级丑数
编写一段程序来寻找第 n 个超级丑数.超级丑数是指其所有质因数都在长度为k的质数列表primes中的正整数.例如,[1, 2, 4, 7, 8, 13, 14, 16, 19, 26, 28, 32] ...
- Leetcode 313. super ugly number
Write a program to find the nth super ugly number. Super ugly numbers are positive numbers whose all ...
- [LeetCode] 264. Ugly Number II 丑陋数 II
Write a program to find the n-th ugly number. Ugly numbers are positive numbers whose prime factors ...
- leetcode 263. Ugly Number 、264. Ugly Number II 、313. Super Ugly Number 、204. Count Primes
263. Ugly Number 注意:1.小于等于0都不属于丑数 2.while循环的判断不是num >= 0, 而是能被2 .3.5整除,即能被整除才去除这些数 class Solution ...
- [LeetCode] Ugly Number II 丑陋数之二
Write a program to find the n-th ugly number. Ugly numbers are positive numbers whose prime factors ...
- [LeetCode] 264. Ugly Number II 丑陋数之二
Write a program to find the n-th ugly number. Ugly numbers are positive numbers whose prime factors ...
随机推荐
- Tensorflow简单实践系列(一):安装和运行
TensorFlow 是谷歌开发的机器学习框架. 安装 TensorFlow 直接使用 pip 安装即可,添加豆瓣镜像可以加快速度: pip install tensorflow -i https:/ ...
- Jmeter连接mysql,如何用delete、update、insert真正删除、更改、插入数据库里的数据;
1.如下图,当插入数据的时候如图对应填写,查询数据的时候上面插入的那条数据就会显示,但是如果不执行下图的提交数据:到数据库里查的时候,插入的这条数据实际上并没有插入成功: . 结果:如果没有提交数据, ...
- Python使用pip安装TensorFlow模块
1.首先确保已经安装python,然后用pip来安装matplotlib模块. 2.进入到cmd窗口下,建议执行python -m pip install -U pip setuptools进行升级. ...
- 如何使用project制定项目计划?(附详细步骤截图)
使用project制定项目计划可以分为六个步骤,如下图(1): 图(1)-project制定项目计划步骤 下面我们就以project2010为例,按上图所示步骤对如何制定项目计划进行详细说明: 一.创 ...
- java中异步调用注意
Future接口是Java标准API的一部分,在java.util.concurrent包中.Future接口是Java线程Future模式的实现,可以来进行异步计算. 有了Future就可以进行三段 ...
- .net Web 项目的文件/文件夹上传下载
以ASP.NET Core WebAPI 作后端 API ,用 Vue 构建前端页面,用 Axios 从前端访问后端 API ,包括文件的上传和下载. 准备文件上传的API #region 文件上传 ...
- 关于H5判定区域里面滑动到底部,加载更多的总结
1.如何判定H5中滑动到底部,然后加载更多的功能实现. 思路:我们需要设定一个固定高度的盒子,然后我们利用scroll来监听滚动,当scrollTop(滚动的距离) + clientHeight(页面 ...
- Python 下载超大文件
使用python下载超大文件, 直接全部下载, 文件过大, 可能会造成内存不足, 这时候要使用requests 的 stream模式, 主要代码如下 iter_content:一块一块的遍历要下载的内 ...
- HTML之微信全屏播放视频
不废话,上代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> < ...
- 解决IE报错[vue router]Failed to resolve async component default:strict 模式下不允许分配到只读属性
之前遇到过一个奇怪的问题,在其他浏览器下一切正常,但在万恶的IE下,却一直不行. 具体问题场景就是:比如orderDetail页面出现问题,那么只要是路由跳转的,点第1次无法跳转,必须得点第2次才可以 ...