leetcode刷题笔记313题 超级丑数

leetcode刷题笔记313题 超级丑数

源地址: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 位有符整数范围内

//思路一 通过维护最小堆,将每次可能的结果压入优先队列,将同样的结果从堆中排除, 直到n个元素出队列即可
import scala.collection.mutable.PriorityQueue
object Solution {
    def nthSuperUglyNumber(n: Int, primes: Array[Int]): Int = {
       val heap = PriorityQueue.empty[Long](Ordering.by(n => n)).reverse
       var count = n

       heap.enqueue(1)
       count -= 1

       while (count > 0) {
           val x = heap.dequeue
           while (heap.length > 0 && heap.head == x) {heap.dequeue}
           for (i <- 0 to primes.length-1) { 
               heap.enqueue(x * primes(i))
            }
           count -= 1
       }

       return heap.dequeue.toInt
    }
}

//基于动态规划 构建dp数组存储丑数序列,index序列存储对应的primes中的质数应该与dp中的那个数求乘积
//而后记录每次的最小值放入, 注意去除重复值
object Solution {
    def nthSuperUglyNumber(n: Int, primes: Array[Int]): Int = {
        val dp = Array.fill(n)(0)
        val index = Array.fill(primes.length)(0)

        dp(0) = 1

        for (i <- 1 to n-1){
            var min = Int.MaxValue
            for (j <- 0 to index.length-1) {
                if (min > primes(j) * dp(index(j))) {min = primes(j) * dp(index(j))}
            }
            dp(i) = min
            for (j <- 0 to index.length-1) {
                if (min == primes(j) * dp(index(j))) {index(j) += 1}
            }
        }

        return dp(n-1)
    }
}
//注意go中堆的使用方法
import "container/heap"

type UglyNums []int

func (u *UglyNums) Push(x interface{}) {
    *u = append(*u, x.(int))
}

func (u *UglyNums) Pop() interface{} {
    n := len(*u)
    x := (*u)[n-1]
    (*u) = (*u)[0:n-1]
    return x
}

func (u UglyNums) Len() int {
    return len(u)
}

func (u UglyNums) Less(i, j int) bool {
    return u[i] < u[j]
}

func (u UglyNums) Swap(i, j int) {
    u[i], u[j] = u[j], u[i]
}

func nthSuperUglyNumber(n int, primes []int) int {
    if n == 0 || n == 1 {return n}
    curHeap := new(UglyNums)
    heap.Push(curHeap, 1)
    n--

    for (n > 0) {
        x := heap.Pop(curHeap).(int)
        for (curHeap.Len() > 0 && (*curHeap)[0] == x) {heap.Pop(curHeap)}
        for i := 0; i < len(primes); i++ {
            heap.Push(curHeap, x*primes[i])
        }
        n -- 
    }

    return heap.Pop(curHeap).(int)
}

//
func nthSuperUglyNumber(n int, primes []int) int {
    length := len(primes)
    dp := make([]int, n)
    index := make([]int, length)

    dp[0] = 1

    for i := 1; i < n; i++ {
        min := math.MaxInt32  
        for j := 0; j < length; j++ {
            if min > primes[j] * dp[index[j]] {min = primes[j] * dp[index[j]]}
        }
        dp[i] = min
        for j := 0; j < length; j++ {
            if min == primes[j] * dp[index[j]] {index[j] += 1}
        } 
    }
    return dp[n-1]
}
posted @ 2020-12-04 19:54  ganshuoos  阅读(96)  评论(0编辑  收藏  举报