Problem Description
Design a number container system that supports two main operations:
- change(index, number): Insert or replace the number at the given index.
- find(number): Return the smallest index that contains the given number (or -1 if none exists).
Key Insights
- We need to support dynamic updates (insertion and replacement) on indices.
- For each number, it is required to quickly determine the minimum index that holds that number.
- A mapping from index to current value helps in tracking replacements.
- For each number we can maintain a heap (or an ordered set) of indices; this allows for efficient retrieval of the smallest available index.
- When updating an index to a new value, the old value’s set must be lazily updated (or cleaned up during retrieval) since the index might still exist in the min-heap of the old value.
Space and Time Complexity
Time Complexity: O(log n) per change and find operation on average (n is the number of indices maintained). Space Complexity: O(n) in the worst-case scenario for storing mappings and heaps for each number.
Solution
We use two main data structures:
- A hash map (or dictionary) "indexMap" to store the current number at each index.
- Another hash map "numToIndices" mapping each number to a min-heap (or balanced BST/ordered set) of indices where that number occurs. When a change(index, number) call is made, we check if the index already exists. If it does, we update the indexMap and add the new index to the heap corresponding to the new number. The outdated index remains in the previous number's heap, and while performing a find operation, we perform lazy deletion: we repeatedly check the top of the heap to verify that the index still maps to the queried number in indexMap. This ensures that the find(number) returns the correct minimal index without expensive heap removal operations.
Code Solutions
Below are code solutions in Python, JavaScript, C++, and Java with line-by-line comments.