🔥🔥||Easy Solution||Beats 100% in most||With proof||C#️⃣🐍🖥️C➕➕✅💎☕||🔥🔥
Hi!! I Have a Deal Here. So If You Upvote My Solution Ill Upvote Yours Too Just Share Your Username In The Comments,!!Have A Nice Day!!💡 IntuitionWe need to cre
![beats 100% .png](https://assets.leetcode.com/users/images/f724619c-ec4d-4e45-996a-a595d88f12b0_1738986860.2000136.png)

Hi!! I Have a Deal Here. So If You Upvote My Solution Ill Upvote Yours Too Just Share Your Username In The Comments,

**!!Have A Nice Day!!**

# 💡 Intuition
We need to create our own small data structure. And it is still unclear how they will be used in practice.But the fact of the matter is that a task is a task that needs to be done.

---


---


# 🚀 Approach
**1. Map Initialization:**
- `map` stores the current number at each index.
- `valIdx` maps each number to a sorted set of indices where the number appears.
**2. Change Operation:**
- If the number is not in `valIdx`, initialize it with an empty sorted set.
- If the index already has a number, remove the index from the sorted set of the previous number.
- Add the index to the sorted set of the new number and update `map`.
**3. Find Operation:**
- Return the smallest index from the sorted set of the given number. If the set is empty, return `-1`.

---


---


# ⌚ Complexity
- Time complexity:
*O(N)Constructor
O(N)Find
O(1)Change*
- Space complexity:
*O(N)Constructor
O(N)Find
O(1)Change*

---



---


Upvote If You Are A **GOAT**(greatest of all time)

---


---


# Code
```cpp []
class NumberContainers {
public:
    unordered_map<int, int> mp;
    unordered_map<int, set<int>> idx;
    NumberContainers() {
        mp.reserve(100000);
    }
    
    void change(int index, int number) {
        if (mp.count(index)){
            int x=mp[index];
            idx[x].erase(index); 
            if (idx[x].size()==0) idx.erase(x);
        }
        mp[index]=number;
        idx[number].insert(index);
    }
    
    int find(int number) {
        if (idx.count(number)==0) 
            return -1;
        return *(idx[number].begin());
    }
};

auto init = []()
{ 
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    return 'c';
}();
/**
 * Your NumberContainers object will be instantiated and called as such:
 * NumberContainers* obj = new NumberContainers();
 * obj->change(index,number);
 * int param_2 = obj->find(number);
 */
```
```java []
import java.util.NoSuchElementException;

class NumberContainers {
    Map<Integer, Integer> map; // Stores the number at each index
    Map<Integer, SortedSet<Integer>> valIdx; // Maps each number to a sorted set of indices

    // Constructor to initialize the maps
    public NumberContainers() {
        map = new HashMap<>();
        valIdx = new HashMap<>();
    }

    // Method to change the number at a given index
    public void change(int index, int number) {
        // If the number is not in valIdx, initialize it with an empty sorted set
        if (!valIdx.containsKey(number)) {
            valIdx.put(number, new TreeSet<>());
        }

        // If the index already has a number, update the frequency map
        if (map.containsKey(index)) {
            if(map.get(index)==number) return;
            int prevVal = map.get(index);
            valIdx.get(prevVal).remove(index); // Remove the index from the sorted set of the previous number
        }

        // Add the index to the sorted set of the new number
        valIdx.get(number).add(index);
        // Update the map with the new number at the given index
        map.put(index, number);
    }

    // Method to find the smallest index for a given number
    public int find(int number) {
        // If the number is in valIdx, return the smallest index from the sorted set
        if (valIdx.containsKey(number)) {
            try {
                return valIdx.get(number).first();
            } catch (NoSuchElementException e) {
                return -1;
            }
        }
        // If the number is not found, return -1
        return -1;
    }
}

/**
 * Your NumberContainers object will be instantiated and called as such:
 * NumberContainers obj = new NumberContainers();
 * obj.change(index,number);
 * int param_2 = obj.find(number);
 */
```
```C# []
public class NumberContainers {

     Dictionary<int, int> indexVal;
 Dictionary<int, PriorityQueue<int, int>> numIndex;

    public NumberContainers() {
         indexVal = new Dictionary<int, int>();
 numIndex = new Dictionary<int, PriorityQueue<int, int>>();
    }
    
     public void Change(int index, int number)
  {
      if (indexVal.ContainsKey(index))
      {
          indexVal[index] = number;
      }
      else
      {
          indexVal.Add(index, number);
      }

      if (numIndex.ContainsKey(number))
      {
          numIndex[number].Enqueue(index, index);
      }
      else
      {
          var pq = new PriorityQueue<int, int>();
          pq.Enqueue(index, index);
          numIndex.Add(number, pq);
      }
  }

  public int Find(int number)
  {
      if (numIndex.ContainsKey(number))
      {
          while (numIndex[number].Count > 0)
          {
              int index = numIndex[number].Peek();

              if (indexVal[index] == number) return index;

              numIndex[number].Dequeue();
          }
      }

      return -1;
  }
}

/**
 * Your NumberContainers object will be instantiated and called as such:
 * NumberContainers obj = new NumberContainers();
 * obj.Change(index,number);
 * int param_2 = obj.Find(number);
 */
```
```javascript []
class NumberContainers {
    constructor() {
        this.indexToNumber = new Map();
        this.numberToIndices = new Map(); 
    }

    change(index, number) {
        if (this.indexToNumber.has(index)) {
            const oldNumber = this.indexToNumber.get(index);
            const oldIndices = this.numberToIndices.get(oldNumber);
            if (oldIndices) {
                oldIndices.delete(index); 
                if (oldIndices.size === 0) {
                    this.numberToIndices.delete(oldNumber);
                }
            }
        }

        this.indexToNumber.set(index, number);
        if (!this.numberToIndices.has(number)) {
            this.numberToIndices.set(number, new MinHeap()); 
        }
        this.numberToIndices.get(number).insert(index);
    }

    find(number) {
        if (!this.numberToIndices.has(number)) {
            return -1;
        }

        const minHeap = this.numberToIndices.get(number);
        return minHeap.size() > 0 ? minHeap.peek() : -1; 
    }
}

class MinHeap {
    constructor() {
        this.heap = [];
        this.indexMap = new Map(); 
    }

    insert(value) {
        this.heap.push(value);
        this.indexMap.set(value, this.heap.length - 1); 
        this.bubbleUp(this.heap.length - 1);
    }

    extractMin() {
        if (this.heap.length === 0) {
            return null;
        }

        const min = this.heap[0];
        this.swap(0, this.heap.length - 1);
        this.indexMap.delete(min); 
        this.heap.pop();
        this.heapifyDown(0);
        return min;
    }

    peek() {
        if (this.heap.length === 0) {
            return null;
        }
        return this.heap[0]; 
    }

    delete(value) {
        const index = this.indexMap.get(value);
        if (index === undefined) {
            return; // Element not found in the heap
        }

        this.swap(index, this.heap.length - 1);
        this.indexMap.delete(value); 
        this.heap.pop();

        this.heapifyDown(index); 
        this.bubbleUp(index); 
    }

    size() {
        return this.heap.length;
    }

    swap(i, j) {
        [this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]];
        this.indexMap.set(this.heap[i], i);
        this.indexMap.set(this.heap[j], j);
    }

    parent(i) {
        return Math.floor((i - 1) / 2);
    }

    left(i) {
        return 2 * i + 1;
    }

    right(i) {
        return 2 * i + 2;
    }

    bubbleUp(i) {
        while (i > 0 && this.heap[i] < this.heap[this.parent(i)]) {
            this.swap(i, this.parent(i));
            i = this.parent(i);
        }
    }

    heapifyDown(i) {
        let smallest = i;
        const left = this.left(i);
        const right = this.right(i);

        if (left < this.heap.length && this.heap[left] < this.heap[smallest]) {
            smallest = left;
        }

        if (right < this.heap.length && this.heap[right] < this.heap[smallest]) {
            smallest = right;
        }

        if (smallest !== i) {
            this.swap(i, smallest);
            this.heapifyDown(smallest);
        }
    }
}
```
```C []
class NumberContainers {
public:
    map<int, int> indexToNumber; // stores number corresponding to an index.
    map<int, set<int>>numberToIndex; // stores all the indexes corresponding to a number.
    NumberContainers() {}
        
    void change(int index, int number) {
        
        if (!indexToNumber.count(index)) { // if there is no number at the given index.
            numberToIndex[number].insert(index); // store index corresponding to the given number
            indexToNumber[index] = number; // store number corresponding to the index.
        }
        else { // Update both map.
            
            int num = indexToNumber[index]; // number at given index currently.
            
            // remove the index
            numberToIndex[num].erase(index); 
            if (numberToIndex[num].empty())    numberToIndex.erase(num);
            
            //  insert the new number at the given index and store the index corresponding to that number.
            numberToIndex[number].insert(index);
            indexToNumber[index] = number;
        }   
    }
    
    int find(int number) {
        if (!numberToIndex.count(number))   return -1;
        // returning first element in the set as it will be the smallest index always.
        return *numberToIndex[number].begin(); 
    }
};
```
```Ruby []
class NumberContainers

    def initialize = (@c, @t = {}, {})

    def change i, n
        p = @c[i]
        if p != n
            @t[p].delete i if p
            @c[i] = n
            @t[n] ||= CRBTreeMap.new
            @t[n][i] = true
        end
    end

    def find(n) = @t[n]&.min_key || -1

end
```
```Rust []
use std::collections::{HashMap,BTreeSet};

struct NumberContainers {
    hash: HashMap<i32,i32>,
    numbers: HashMap<i32,BTreeSet<i32>>
}

impl NumberContainers {

    fn new() -> Self {
        NumberContainers{hash:HashMap::new(),numbers:HashMap::new()}
    }
    
    fn change(&mut self, index: i32, number: i32) {
        if self.hash.contains_key(&index) {
            if self.numbers.contains_key(&self.hash[&index]) {
                self.numbers.get_mut(&self.hash[&index]).unwrap().remove(&index);
            }
        }
        *self.hash.entry(index).or_insert(number) = number;
        self.numbers.entry(number).or_insert(BTreeSet::new()).insert(index);
    }
    
    fn find(&self, number: i32) -> i32 {
        if self.numbers.contains_key(&number) {
            if let Some(idx) = self.numbers[&number].first() {
                return *idx;
            }
        }
        -1
    }
}
```
```python3 []
class NumberContainers:

    def __init__(self):
        self.index_num = {} # index: num at index
        self.num_indices = {} # num: min heap of indices where num has been

    def change(self, index: int, number: int) -> None:
        self.index_num[index] = number # set number for index
        
        if number not in self.num_indices: 
            self.num_indices[number] = [] # make heap if new num
        heapq.heappush(self.num_indices[number], index) # add index to min heap

    def find(self, number: int) -> int:
        if number not in self.num_indices: 
            return -1 # no index with number
            
        pos_indices = self.num_indices[number]
        while pos_indices:
            min_index = pos_indices[0] # check lowest index
            
            if self.index_num[min_index] == number: 
                return min_index # valid index, found num at index

            heapq.heappop(pos_indices) # invalid index, new num at index
        
        return -1 # no valid index found
```
```python []
class NumberContainers:
    def __init__(self):
        self.numbersByIndex = {}
        self.numberIndexes = defaultdict(set)
        self.numberIndexesHeap = defaultdict(list)

    def change(self, index: int, number: int) -> None:
        if index in self.numbersByIndex:
            if number != self.numbersByIndex[index]:
                self.numberIndexes[self.numbersByIndex[index]].remove(index)
                self.numbersByIndex[index] = number
                self.numberIndexes[number].add(index)
                heappush(self.numberIndexesHeap[number], index)
        else:
            self.numbersByIndex[index] = number
            self.numberIndexes[number].add(index)
            heappush(self.numberIndexesHeap[number], index)

    def find(self, number: int) -> int:
        while self.numberIndexesHeap[number] and self.numberIndexesHeap[number][0] not in self.numberIndexes[number]:
                heappop(self.numberIndexesHeap[number])  # make sure the smallest index in heap is still an index for number
        return self.numberIndexesHeap[number][0] if self.numberIndexesHeap[number] else -1
```
```Swift []
class NumberContainers {
    var indexToNumber = [Int: Int]()
    var numberToIndices = [Int: Heap<Int>]()

    func change(_ index: Int, _ number: Int) {
        indexToNumber[index] = number
        numberToIndices[number, default: Heap()].insert(index)
    }
    
    func find(_ number: Int) -> Int {
        while let index = numberToIndices[number]?.min {
            if indexToNumber[index] == number { return index }
            numberToIndices[number]?.popMin()
        }
        return -1
    }
}
```
![plez upvote.png](https://assets.leetcode.com/users/images/c0689ef7-030f-4f6b-a4c3-a868f6c794f1_1738986867.0608995.png)

['Swift', 'C', 'Python', 'C++', 'Java', 'Python3', 'Rust', 'Ruby', 'JavaScript', 'C#']