↓快轉到主要內容
  1. LeetCode/

LeetCode 264: Ugly Number II

·1 分鐘· ·
LeetCode Medium Hash-Table Math Dynamic-Programming Heap-Priority-Queue
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試:2022-11-14

  • 提交紀錄:Time Limit Exceeded ×3 → Accepted ×3

解題思路
#

每個醜數都是某個更小的醜數乘上 2、3 或 5。維護三個指針 i2、i3、i5,下一個醜數是 min(u[i2] * 2, u[i3] * 3, u[i5] * 5),然後所有等於這個值的指針都要前進,避免重複(例如 6 = 2 × 3 = 3 × 2)(Linear DP 模板一)。

我的嘗試
#

前三版從 1 開始逐一檢查每個整數是不是醜數(第二版還加了 seen 集合),但第 n 個醜數可能很大,一個一個檢查太慢,TLE 了三次。改成三指針才 AC。

正確解法
#

class Solution:
    def nthUglyNumber(self, n: int) -> int:
        u = [1]
        i2 = i3 = i5 = 0
        while len(u) < n:
            nxt = min(u[i2] * 2, u[i3] * 3, u[i5] * 5)
            u.append(nxt)
            if nxt == u[i2] * 2: i2 += 1
            if nxt == u[i3] * 3: i3 += 1
            if nxt == u[i5] * 5: i5 += 1
        return u[-1]

複雜度
#

時間 O(n),空間 O(n)。

要特別避免的錯誤
#

  • 三個 if 要分開寫,不能用 elif:相同的值要讓所有對應的指針都前進。
  • 從 1 開始逐一檢查是不是醜數會 TLE,第 1690 個醜數超過 20 億。

面試口說整理
#

每個醜數都是更小的醜數乘上 2、3 或 5,我用三個指針指向下一個要乘的醜數,每次取三個乘積的最小值,等於它的指針都往前,避免重複。時間 O(n)。

相關文章

LeetCode 187: Repeated DNA Sequences
·1 分鐘
LeetCode Medium Hash-Table String Bit-Manipulation Sliding-Window
LeetCode 187 解題筆記:把每個長度 10 的子字串丟進雜湊表計數,出現超過一次的就是答案
LeetCode 50: Pow(x, n)
·1 分鐘
LeetCode Medium Math Recursion
LeetCode 50 解題筆記:快速冪,x^n = (x²)^(n/2),n 是奇數時多乘一個 x;n 是負數時算 1 / x^(-n)
LeetCode 227: Basic Calculator II
·1 分鐘
LeetCode Medium Math String Stack
LeetCode 227 解題筆記:先把數字讀完整,遇到運算子時處理上一個運算子:+ - 把數放進 stack(減號放負數),* / 直接跟頂端算
LeetCode 229: Majority Element II
·1 分鐘
LeetCode Medium Array Hash-Table Sorting Counting
LeetCode 229 解題筆記:超過 n / 3 的數最多兩個;Boyer-Moore 維護兩個候選人,最後再掃一次確認次數
LeetCode 189: Rotate Array
·1 分鐘
LeetCode Medium Array Math Two-Pointers
LeetCode 189 解題筆記:先 k %= n,再用三次反轉:整個反轉、前 k 個反轉、後 n - k 個反轉;O(1) 額外空間
LeetCode 204: Count Primes
·1 分鐘
LeetCode Medium Array Math Enumeration Number-Theory
LeetCode 204 解題筆記:埃氏篩,只用質數 p 從 p² 開始把倍數劃掉,外層只要到 √n