MediumArrayMathDesignData StreamPrefix SumUpdated Sep 2026

1352. Product of the Last K Numbers

Asked at TikTok

Difficulty

Medium

Time

O(1) per add and O(1) per getPro

Space

O(n)

Pattern

Array

Companies

1

Problem

Design a class that stores a stream of integers and can answer queries about the product of the most recent numbers.

You must implement three methods. The constructor ProductOfNumbers() starts with an empty stream. add(num) puts num at the end of the stream. getProduct(k) returns the product of the last k numbers currently in the stream. It is guaranteed that the stream always holds at least k numbers when getProduct is called.

A naive getProduct multiplies k numbers every time, which is slow when k is large. The goal (and the follow-up challenge) is to make both add and getProduct run in constant time. Hint: keep running prefix products, and handle the value 0 carefully, because a zero makes division impossible.

What getProduct(k) asks for

streamk = 23025401234getProduct(2) looks at the last two values: 5 * 4 =20.streamk = 43025401234getProduct(4) reaches back over the 0, so the wholeproduct becomes 0.
getProduct(k) multiplies the k most recent values, so the window slides with every new add.

Constraints

  • ●0 <= num <= 100
  • ●1 <= k <= 4 * 10^4
  • ●At most 4 * 10^4 total calls to add and getProduct
  • ●The product of any contiguous sequence in the stream fits in a 32-bit integer

Examples

Example 1
Input["ProductOfNumbers","add","add","add","add","add","getProduct","getProduct","getProduct","add","getProduct"] [[],[3],[0],[2],[5],[4],[2],[3],[4],[8],[2]]
Output[null,null,null,null,null,null,20,40,0,null,32]
WhyAfter adding 3, 0, 2, 5, 4 the stream is [3,0,2,5,4]. The last 2 numbers are 5 and 4, so 5*4 = 20. The last 3 are 2,5,4, so 2*5*4 = 40. The last 4 include the 0, so the product is 0. After adding 8, the last 2 numbers are 4 and 8, so 4*8 = 32.

Asked At

1 companies
CompanyDifficulty
TikTokMediumView all TikTok questions →

How to Think About It

1

Multiplying the last k numbers on each query is O(k) per call.

2

Key insight: like prefix sums, keep prefix products. The product of the last k numbers is prefix[-1] / prefix[-1 - k].

3

Zeros break division. Handle them by resetting: when 0 is added, clear the prefix list back to [1]. Any query whose window reaches back past that zero must return 0.

4

So after a reset, if k is at least the number of values added since the last zero (k >= len(prefix)), the window contains the zero — return 0.

5

Walkthrough: add 3, 0, 2, 5, 4 -> prefix after the zero is [1, 2, 10, 40]. getProduct(2) = 40 / 2 = 20. getProduct(4) reaches the zero -> 0.

Optimal Approach

State: prefix = [1].

add(num): if num == 0, reset prefix = [1]; else append prefix[-1] * num.
getProduct(k): if k >= len(prefix), return 0; else return prefix[-1] // prefix[-1 - k].

The problem guarantees that products of the current list fit in a 32-bit integer, so the prefix values never overflow.

Time: O(1) per operation. Space: O(n).

Prefix products with a zero reset

prefix1301After add(3): prefix = [1, 3], where prefix[i] is theproduct of the first i values.prefix10add(0) resets prefix back to [1]; the zero is now awall we cannot divide past.prefix1210400123After add(2), add(5), add(4): prefix = [1, 2, 10, 40]for the values since the zero.add(num): 0 -> reset to [1], else append last*numgetProduct(k): k >= len(prefix) -> 0else prefix[-1] // prefix[-1-k]
A zero clears the prefix list, so any window that crosses it is answered with 0.
ComplexityTime O(1) per add and O(1) per getProSpace O(n)Each add appends one prefix product and each query does one division, so the cost is constant per call; the prefix list grows with the number of non-zero adds.

What Trips People Up in Real Interviews

1

Dividing by a zero prefix. Resetting on zero avoids it and makes the zero check a simple length comparison.

2

Storing the raw numbers and multiplying per query — O(k) each time.

3

Off-by-one in the zero check: the window of the last k numbers includes the zero exactly when k >= len(prefix).

4

Forgetting the overflow discussion. Here the problem bounds the product, but mention that without that guarantee you would need big integers or logs.

Solution Code

O(1) per add and O(1) per getPro time
class ProductOfNumbers:
    def __init__(self):
        self.prefix = [1]

    def add(self, num):
        if num == 0:
            self.prefix = [1]
        else:
            self.prefix.append(self.prefix[-1] * num)

    def getProduct(self, k):
        if k >= len(self.prefix):
            return 0
        return self.prefix[-1] // self.prefix[-1 - k]

Pro at DSA?

Test your skills with a real FAANG-style mock interview.

Start a Mock Interview →

Frequently Asked Questions

What is the Product of the Last K Numbers problem?

Product of the Last K Numbers asks you to design a stream that supports `add(num)` and `getProduct(k)`, which returns the product of the last `k` numbers. Prefix products make queries `O(1)` — as long as you handle zeros, which would otherwise break division.

How do you solve Product of the Last K Numbers?

The optimal approach runs in O(1) per add and O(1) per getPro time and O(n) space. Scroll up to "Optimal Approach" for the step-by-step walkthrough, diagrams, and code in Python, C++ and Java.

What companies ask Product of the Last K Numbers?

Product of the Last K Numbers is asked at TikTok. It is a medium difficulty problem.

What are common mistakes on Product of the Last K Numbers?
  • Dividing by a zero prefix. Resetting on zero avoids it and makes the zero check a simple length comparison.
  • Storing the raw numbers and multiplying per query — `O(k)` each time.
  • Off-by-one in the zero check: the window of the last `k` numbers includes the zero exactly when `k >= len(prefix)`.
  • Forgetting the overflow discussion. Here the problem bounds the product, but mention that without that guarantee you would need big integers or logs.