↓Skip to main content
  1. LeetCode/

LeetCode 313: Super Ugly Number

·2 mins· ·
LeetCode Medium Array Math Dynamic-Programming
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2022-11-16

  • Submissions: Wrong Answer ×2 → Output Limit Exceeded → Accepted → Wrong Answer → Accepted → Output Limit Exceeded → Wrong Answer → Output Limit Exceeded → Wrong Answer

Approach
#

As in LC 264, each prime p has a pointer idx[p]; the next value is the minimum of u[idx[p]] * p, and every matching pointer advances, in O(nk).

A heap version must handle duplicates: 6 is pushed both as 2 × 3 and 3 × 2. One trick is, after popping x, to multiply only by primes up to x’s smallest prime factor (stop once x % p == 0), so each number is generated exactly once, as its smallest prime factor times the rest (Heap).

My Attempts
#

I wrote this with a heap and failed 8 times, all about duplicates:

  • 2022-11-16: after popping p I pushed p times each prime, stopping only when p == prime, which stops only if p is itself prime; composites such as 6 still produced duplicates, the same number was popped twice, and the answers shifted.
  • 2022-11-26: some versions dropped the stopping rule entirely, making more duplicates; changing it to p % prime == 0 (stop at p’s smallest prime factor) passed. Three more were Output Limit Exceeded from prints.

Solution
#

class Solution:
    def nthSuperUglyNumber(self, n: int, primes: List[int]) -> int:
        u = [1]
        idx = [0] * len(primes)
        while len(u) < n:
            nxt = min(u[idx[k]] * p for k, p in enumerate(primes))
            u.append(nxt)
            for k, p in enumerate(primes):
                if u[idx[k]] * p == nxt:
                    idx[k] += 1
        return u[-1]

Complexity
#

Time O(nk) for k primes, space O(n + k).

Mistakes to Avoid
#

  • Without deduplication a heap pops the same number many times.
  • The stopping rule is x % p == 0 (p is x’s smallest prime factor), not x == p.

Interview Explanation
#

Generalizing LC 264, each prime has a pointer to the next ugly number to multiply; I take the smallest product and advance every matching pointer, in O(nk). A heap also works if duplicates are avoided.

Related

LeetCode 396: Rotate Function
·2 mins
LeetCode Medium Array Math Dynamic-Programming
LeetCode 396 note: F(k) and F(k - 1) differ by one formula: F(k) = F(k - 1) + sum - n × the element moved to the front
LeetCode 435: Non-overlapping Intervals
·2 mins
LeetCode Medium Array Dynamic-Programming Greedy Sorting
LeetCode 435 note: minimum removals = total minus the maximum kept; sort by right end and greedily keep the one ending earliest
LeetCode 473: Matchsticks to Square
·2 mins
LeetCode Medium Array Dynamic-Programming Backtracking Bit-Manipulation
LeetCode 473 note: the total must be divisible by 4; place sticks from longest to shortest into one of four sides, skipping a side that would overflow or that equals a side already tried
LeetCode 264: Ugly Number II
·2 mins
LeetCode Medium Hash-Table Math Dynamic-Programming Heap-Priority-Queue
LeetCode 264 note: three pointers mark the next ugly numbers to multiply by 2, 3 and 5; take the minimum each time and advance every pointer that produced it
LeetCode 189: Rotate Array
·2 mins
LeetCode Medium Array Math Two-Pointers
LeetCode 189 note: take k %= n, then reverse three times: the whole array, the first k, and the last n - k, with O(1) extra space
LeetCode 204: Count Primes
·2 mins
LeetCode Medium Array Math Enumeration Number-Theory
LeetCode 204 note: the sieve of Eratosthenes, crossing out multiples of each prime p starting at p², with the outer loop only up to √n