leetcode刷題筆記313題 超級醜數
阿新 • • 發佈:2020-12-04
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] }