LeetCode_堆(2)264.丑数,313.超级丑数

目录

264. 丑数 II

313. 超级丑数

264和313思路相同

264. 丑数 II

编写一个程序,找出第 n 个丑数。

丑数就是只包含质因数 2, 3, 5 的正整数

示例:

输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。

说明:  

1 是丑数。  n 不超过1690

方法1.

class Tool {
  public int[] nums = new int[1690];
  Tool() {
    HashSet<Long> seen = new HashSet();
    PriorityQueue<Long> heap = new PriorityQueue<Long>();
    seen.add(1L);
    heap.add(1L);

    long cur, New;
    int[] primes = new int[]{2, 3, 5};
    for(int i = 0; i < 1690; ++i) {
      cur = heap.poll();
      nums[i] = (int)cur;
      for(int j : primes) {
        New = cur * j;
        if (!seen.contains(New)) {
          seen.add(New);
          heap.add(New);
        }
      }
    }

  }
}

class Solution {
  public static Tool u = new Tool();
  public int nthUglyNumber(int n) {
    return u.nums[n - 1];
  }
}

方法2.    87.75%,90.37%

class Solution {
public:
    int min(int a,int b,int c){
        return a>b?(b<c?b:c):(a<c?a:c);
    }
    int nthUglyNumber(int n) {
        int* u=new int[n];
        u[0]=1;
        int index2=0;
        int index3=0;
        int index5=0;
        int k=1;
        while(k<n){
            u[k]=min(u[index2]*2,u[index3]*3,u[index5]*5);
            if(u[index2]*2==u[k])index2++;
            if(u[index3]*3==u[k])index3++;
            if(u[index5]*5==u[k])index5++;
            k++;
        }
        return u[n-1];
    }
};

313. 超级丑数

编写一段程序来查找第 n 个超级丑数。

超级丑数是指其所有质因数都是长度为 k 的质数列表 primes 中的正整数。

示例:

输入: 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] 。

说明:

  • 1 是任何给定 primes 的超级丑数。
  •  给定 primes 中的数字以升序排列。
  • 0 < k ≤ 100, 0 < n ≤ 106, 0 < primes[i] < 1000 。
  • 第 n 个超级丑数确保在 32 位有符整数范围内

方法1. heap实现

class Solution {
  private int[] nums = new int[1000000];
  public void solve(int n, int[] primes){
    HashSet<Long> seen = new HashSet();
    PriorityQueue<Long> heap = new PriorityQueue<Long>();
    seen.add(1L);
    heap.add(1L);

    long cur, New;
    for(int i = 0; i < n; ++i) {
      cur = heap.poll();
      nums[i] = (int)cur;
      for(int j : primes) {
        New = cur * j;
        if (!seen.contains(New)) {
          seen.add(New);
          heap.add(New);
        }
      }
    }  
  }
  public int nthSuperUglyNumber(int n, int[] primes) {
        solve(n,primes);
        return nums[n - 1];
  }
    
}

上面这个思路倒是简单,但是5.08%,5.47%。。。

方法2. 

class Solution {
public:
    int nthSuperUglyNumber(int n, vector<int>& primes) {
        int k = primes.size(),i,j;
        vector<int> uglynum(n,1),idx(k,0),a(k,0);
        for(i = 1; i < n; i++)
        {
            int minnum = 2147483647;
            for(j = 0; j < k; j++)
            {
                a[j] = uglynum[idx[j]]*primes[j];
                if(a[j] < minnum)
                    minnum = a[j];
            }
            for(j = 0; j < k; j++)
            {
                if(a[j] == minnum)
                    ++idx[j];
            }
            uglynum[i] = minnum;
        }
        return uglynum[n-1];
    }
};
class Solution(object):
     def nthSuperUglyNumber(self,n,primes):
         dp = [1] # 超级丑数列表
         idx = [0]*len(primes) # 质数因子的指针列表,初始都指向0,即dp[0]
         plen = len(primes) # 
         while n>1: # 添加了n-1个超级丑数,停止
             # 取出质数列表中的每个质数与各自指针对应的超级丑数相乘的最小值
             min_ = min([dp[idx[i]]*primes[i] for i in range(plen)])
             for i in range(plen):
                 #若最小值等于该质数乘以dp[idx[i]](第i个质数的指针所对应的超级丑数)
                 #则对应指针往后移动一步,i+1
                 if min_==dp[idx[i]]*primes[i]: 
                     idx[i] += 1
             n -= 1
             dp.append(min_)
         return dp[-1]
发布了88 篇原创文章 · 获赞 77 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43107805/article/details/105019641
今日推荐