313. Super Ugly Number

网址:
https://leetcode.com/problems/super-ugly-number/

Hint:
https://leetcode.com/problems/ugly-number-ii/ 为此题的特殊情况,aka简化版,可先看或忽略

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 given primes = [2,7,13,19] of size 4.

Solution1
思路:
maintain一个minHeap,一共pop n次,每pop一次,将pop出的数与prime中每一个相乘,存入heap中
Error1:
忘记去重,pop 2时,offer 2 * 7,pop 7时,重复offer 14,故添加Set deduplicate
复杂度:
k = prime.length
Time: O(n * k * log(nk))
Space: O(n * k)

public int nthSuperUglyNumber(int n, int[] primes) {
        PriorityQueue<Integer> qp = new PriorityQueue<>();
        Set<Integer> dedup = new HashSet<>();
        qp.offer(1);
        dedup.add(1);
        while(n > 1) {
            n--;
            int cur = qp.poll();
            for (int prime : primes) {
                int multi = prime * cur;
                if (!dedup.contains(multi)) {
                //offer Time compelexity: log(size)
                    qp.offer(multi);
                    dedup.add(multi);
                }                
            }
        }
        return qp.poll();
    }

问题:超时
原因:当n * k很大时,每次offer都需要log(nk),超时。其实后面的super 大的数字都用不到,我们只需要前n个数

Solution2
思路:
已知,每次的当前最小值,只可能是已生成的ugly number与prime数组中的数相乘而得到
添加一个idx数组,保存for prime中的每一个数,已经与那些已生成ugly数组中的数相乘完毕,i.e.,下一个可能最小值是由prime与ugly[index]产生
Hint:同理,第二个j的for循环,deduplicate
复杂度:
k = prime.length
Time: O(n * k)
Space: O(n * k)

public int nthSuperUglyNumber(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++) {
	        if (primes[j] * ugly[idx[j]] == ugly[i]) {
	        		idx[j]++;
	        }
	    }
	}
	return ugly[n - 1];
    }

to do
https://leetcode.com/problems/super-ugly-number/discuss/?orderBy=most_votes
还有两个优化 or trade off,等我缓缓明天复习再看

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值