C# Solution for Product of the Last K Numbers Problem
IntuitionThe problem requires efficiently computing the product of the last k numbers while dynamically adding new numbers to the stream. A naive approach itera
# Intuition
<!-- Describe your first thoughts on how to solve this problem. -->
The problem requires efficiently computing the product of the last k numbers while dynamically adding new numbers to the stream. A naive approach iterating over the last k numbers leads to  O(k)  time complexity, which is inefficient for large k values (up to  4 \times 10^4 ).

To optimize, we use prefix product multiplication, where each index in the list stores the cumulative product of all previous numbers. Using division, we can retrieve the product of any subarray in  O(1)  time.

# Approach
<!-- Describe your approach to solving the problem. -->
1.	Use a Prefix Product List (prefixProduct)
	•	Maintain a list where prefixProduct[i] stores the product of all numbers from the beginning up to index i.
	•	Start with 1 in the list to handle multiplications easily.
2.	Adding a Number (Add(num))
	•	If num == 0, reset prefixProduct since all previous products become irrelevant (multiplication by zero results in zero).
	•	Otherwise, compute the new cumulative product as:

    prefixProduct[i] = prefixProduct[i-1] x num

	•	This ensures that each index contains the product of all previous elements.
3.	Fetching the Product (GetProduct(k))
	•	If k exceeds the number of valid elements since the last zero, return 0.
	•	Otherwise, retrieve the product in  O(1)  using:

    product = frac{prefixProduct[n-1]}{prefixProduct[n-k-1]}

	•	This efficiently calculates the product using a single division.

# Complexity
- Time complexity:
<!-- Add your time complexity here, e.g. $$O(n)$$ -->
- Add(int num) - O(1) - Appends to the list and performs a multiplication.
- GetProduct(int k) - O(1) - Uses division to compute the product in constant time.

- Space complexity:
<!-- Add your space complexity here, e.g. $$O(n)$$ -->
Worst Case - O(N) - Stores at most N prefix products.
Best Case - O(1) - If zero appears frequently, the list resets, minimizing storage.

# Code
```csharp []
public class ProductOfNumbers {
    private List<int> prefixProduct;
    public ProductOfNumbers() {
        prefixProduct = new List<int>();
        prefixProduct.Add(1);
    }
    
    public void Add(int num) {
        if (num == 0) {
            prefixProduct.Clear();
            prefixProduct.Add(1); 
        } else {
            int lastProduct = prefixProduct[prefixProduct.Count - 1];
            prefixProduct.Add(lastProduct * num);
        }
    }
    
    public int GetProduct(int k) {
        int n = prefixProduct.Count;
        if (k >= n) {
            return 0; 
        }
        return prefixProduct[n - 1] / prefixProduct[n - k - 1];
    }
}

/**
 * Your ProductOfNumbers object will be instantiated and called as such:
 * ProductOfNumbers obj = new ProductOfNumbers();
 * obj.Add(num);
 * int param_2 = obj.GetProduct(k);
 */
```
['C#']