Efficient Ordered Set & HashMap Approach
IntuitionThe problem requires efficiently mapping numbers to indices while supporting dynamic updates and queries. A naive approach using arrays would be ineffi
# Intuition
The problem requires efficiently mapping numbers to indices while supporting dynamic updates and queries. A naive approach using arrays would be inefficient, so we use two hash maps to maintain the bidirectional relationships.

# Approach
1. **Data Structures Used:**
   - `unordered_map<int, int> indexToVal`: Maps an index to its assigned number.
   - `unordered_map<int, set<int>> ValToIndex`: Maps a number to a sorted set of indices where it appears.
   
2. **Operations:**
   - `change(index, number)`:  
     - If the index already has a number, remove it from `ValToIndex`.
     - Update the mapping in `indexToVal`.
     - Insert the index into `ValToIndex[number]`.
   - `find(number)`:  
     - If `number` exists in `ValToIndex`, return the smallest index from the set.
     - Otherwise, return `-1`.

3. **Efficiency Considerations:**
   - Using `unordered_map` allows for **O(1)** average-time lookups.
   - Using `set<int>` ensures indices remain sorted, allowing efficient retrieval of the smallest index in **O(1)** time.

# Complexity
- **Time Complexity:**
  - `change()`: **O(log n)** (due to `set.insert()` and `set.erase()` operations).
  - `find()`: **O(1)** (retrieving the first element of a set).
  
- **Space Complexity:**  
  - **O(n)** for storing indices and values in the maps.



# Code
```cpp []
class NumberContainers {
private:
    unordered_map<int, int> indexToVal;
    unordered_map<int, set<int>> ValToIndex; 
public:
    NumberContainers() {
        
    }
    
    void change(int index, int number) {
        
        if (indexToVal.find(index) != indexToVal.end()) {

            int oldVal = indexToVal[index];
            ValToIndex[oldVal].erase(index);
            if (ValToIndex[oldVal].size() == 0) {
                ValToIndex.erase(oldVal);
            }
        }

        indexToVal[index] = number;
        ValToIndex[number].insert(index);
    }
    
    int find(int number) {
        
        if (ValToIndex.find(number) == ValToIndex.end()) return -1;
        return *ValToIndex[number].begin();
    }
};

/**
 * Your NumberContainers object will be instantiated and called as such:
 * NumberContainers* obj = new NumberContainers();
 * obj->change(index,number);
 * int param_2 = obj->find(number);
 */
```
['Hash Table', 'Design', 'Ordered Set', 'C++']