🔥BEATS 💯 % 🎯 |✨SUPER EASY BEGINNERS 👏| JAVA | C | C++ | PYTHON| JAVASCRIPT | DART 
IntuitionThe problem requires us to efficiently store and retrieve indices associated with numbers while handling updates dynamically.
change(index, number): As
![image.png](https://assets.leetcode.com/users/images/c1f9d0af-b6e6-459e-9d43-48b434d50999_1739023237.1061463.png)

---


# **Intuition**
The problem requires us to efficiently **store and retrieve indices** associated with numbers while handling updates dynamically.

- **change(index, number)**: Assigns a number to an index. If the index already had a different number, update it.
- **find(number)**: Returns the smallest index where the number appears.

To achieve **efficient lookups and updates**, we use:
- A **HashMap** (`store`) to map each index to its assigned number.
- A **TreeSet** (`_rec`) to maintain indices in **sorted order** for each number.

---

# **Approach**
1. **Data Structures Used**:
   - `store`: Maps `index → number` (helps track updates).
   - `_rec`: Maps `number → SortedSet of indices` (stores indices in increasing order).

2. **Operations**:
   - **change(index, number)**
     - If `index` exists in `store`, remove it from the previous number’s set.
     - Assign the new `number` to `index` in `store`.
     - Add `index` to `_rec[number]`, ensuring it's stored in sorted order.

   - **find(number)**
     - If `_rec[number]` is non-empty, return the **smallest index**.
     - Otherwise, return `-1`.

3. **Efficiency**:
   - **change()** takes **O(log N)** (because of `SplayTreeSet` insertion/removal).
   - **find()** takes **O(1)** (direct access to the first element of `SplayTreeSet`).

---

# **Complexity Analysis**
- **Time Complexity**:
  - **change()** → **O(log N)** (modifying a sorted set).
  - **find()** → **O(1)** (constant-time lookup).

- **Space Complexity**:
  - **O(N)** (for storing indices and numbers in hash maps).

---


```dart []
import 'dart:collection';

class NumberContainers {
  // Maps index to the number stored at that index
  Map<int, int> store = {};

  // Maps a number to a sorted set of indices where it appears
  Map<int, SplayTreeSet<int>> _rec = {};

  NumberContainers();

  void change(int index, int number) {
    // If index already contains a number, remove the old mapping
    if (store.containsKey(index)) {
      int oldNumber = store[index]!;
      _rec[oldNumber]?.remove(index);
      if (_rec[oldNumber]?.isEmpty ?? false) {
        _rec.remove(oldNumber);
      }
    }

    // Assign new number to index
    store[index] = number;

    // Add index to the sorted set for this number
    _rec.putIfAbsent(number, () => SplayTreeSet<int>()).add(index);
  }

  int find(int number) {
    return _rec.containsKey(number) && _rec[number]!.isNotEmpty ? _rec[number]!.first : -1;
  }
}
```


```java []
import java.util.*;

class NumberContainers {
    Map<Integer, Integer> store;
    Map<Integer, TreeSet<Integer>> rec;

    public NumberContainers() {
        store = new HashMap<>();
        rec = new HashMap<>();
    }

    public void change(int index, int number) {
        if (store.containsKey(index)) {
            int oldNumber = store.get(index);
            rec.get(oldNumber).remove(index);
            if (rec.get(oldNumber).isEmpty()) {
                rec.remove(oldNumber);
            }
        }
        store.put(index, number);
        rec.putIfAbsent(number, new TreeSet<>());
        rec.get(number).add(index);
    }

    public int find(int number) {
        return rec.containsKey(number) && !rec.get(number).isEmpty() ? rec.get(number).first() : -1;
    }
}
```


```javascript []
class NumberContainers {
    constructor() {
        this.store = new Map();
        this.rec = new Map();
    }

    change(index, number) {
        if (this.store.has(index)) {
            let oldNumber = this.store.get(index);
            this.rec.get(oldNumber).delete(index);
            if (this.rec.get(oldNumber).size === 0) {
                this.rec.delete(oldNumber);
            }
        }
        this.store.set(index, number);
        if (!this.rec.has(number)) this.rec.set(number, new Set());
        this.rec.get(number).add(index);
    }

    find(number) {
        return this.rec.has(number) && this.rec.get(number).size > 0 ? Math.min(...this.rec.get(number)) : -1;
    }
}
```


```cpp []
#include <unordered_map>
#include <set>
using namespace std;

class NumberContainers {
private:
    unordered_map<int, int> store;
    unordered_map<int, set<int>> rec;

public:
    NumberContainers() {}

    void change(int index, int number) {
        if (store.find(index) != store.end()) {
            int oldNumber = store[index];
            rec[oldNumber].erase(index);
            if (rec[oldNumber].empty()) {
                rec.erase(oldNumber);
            }
        }
        store[index] = number;
        rec[number].insert(index);
    }

    int find(int number) {
        return (rec.find(number) != rec.end() && !rec[number].empty()) ? *rec[number].begin() : -1;
    }
};
```


```python []
class NumberContainers:
    def __init__(self):
        self.store = {}  # Maps index -> number
        self.rec = {}    # Maps number -> sorted set of indices

    def change(self, index: int, number: int) -> None:
        if index in self.store:
            old_number = self.store[index]
            self.rec[old_number].discard(index)
            if not self.rec[old_number]:
                del self.rec[old_number]

        self.store[index] = number
        if number not in self.rec:
            self.rec[number] = set()
        self.rec[number].add(index)

    def find(self, number: int) -> int:
        return min(self.rec[number]) if number in self.rec and self.rec[number] else -1
```


---

![image.png](https://assets.leetcode.com/users/images/d81a7cee-fa73-41a2-82dc-65bf475d960c_1722267693.3902693.png) {:style='width:250px'}
['Hash Table', 'Design', 'C', 'Ordered Set', 'C++', 'Java', 'Python3', 'JavaScript', 'Dart']