Step By Step Intuitively Explained Solution
IntuitionTwo maps, one for storing index to number mapping and other for storing number to indices.ApproachSo, our requirement is, we need to know what index is
# Intuition
<!-- Describe your first thoughts on how to solve this problem. -->
Two maps, one for storing index to number mapping and other for storing number to indices.
# Approach
<!-- Describe your approach to solving the problem. -->
So, our requirement is, we need to know what index is mapped with what number. Also, what number have what indices so that we can get the least index value.
If you think we can simply map the lowest index number and replace it with a smaller index whenever we find one, you're not alone in this thought journey. That is a good start.
But, if you move forward in that path, you will stumble upon with a problem.
Let's first take an example and try to understand this step by step.
Let us say, we created two maps to store index to number (iton) and number to index (ntoi).
Now, if the change is [2, 10].
Then `2 -> 10` and `10 -> 2` are maps respectively.
Now, if we find 10, then we check ntoi and return 2.
Next, the change is [1, 10]. Yes we found lower indexing for 10.
We update the maps with `1 -> 10, 2 ->10` and `10 -> 1`.
If we need to find 10, we return 1.
It is good until this point.
Now, if the change is [1, 12].
Then updated maps will be `1 -> 12, 2 ->10` and `12 -> 1`.
Here, the problem arises. Now, what should we map 10 with? It should not be 1 anymore. SO, if we remove it then when we find 10, we get -1. But, there index 2 which mapped to 10.
Ahhhhh!!
This means we need to know at What all indexes this number is.
Okay, then let us take an array and store index associated with the number instead of just the lowest one.
Well, it sounds good. But again, everytime there is change in index, you need to go through all the array of the number just to change it right!!! Also, the finding that in the array will cost of lot of time.
Then what to do. Let's start optimising it. How can we optimize a search? We can use binary searching if we have a sorted array. Cool, that is good choice. What else we can use? 
Think, I know you can get it.
MIN HEAP!
If we have a min heap/ priority queue, then we always have a sorted order of the indexes.
Okay now what about updation? If we have min heap, it is hard to remove a element from somewhere in the middle of the queue. i.e., if we have 10 mapped to 1,2,3,4,5 in the queue and index 4 is getting updated, It will be hard remove 4 from the queue of 10.

Well, why we should remove 4?
Did not understand?
Think, when we need to find 10, we will have the least index in the front of the queue. Let's say 1 in the front. Now, there is a chance that 1 also mapped to something else at somepoint. Aww! Then let's simply check whether 1 mapped to 10 or not and pop it and go to next element. Likewise pop all that are not mapped to 10 and simply return the first value which mapped to 10. If the queue became empty in the process, then simply return -1. In this way, we can update the queue whenever we actually want to find the element. This is also called **Lazy Update** Technique.

Now, to conclude, Have 2 maps one for index to number and another for number to indices mapping. For change, change the index mapping to new number and push new index in the priority queue of the number. For find, go to the queue of the number, pop until we find the front value index was mapped with the number and return it.

That's it guys. Hope you understood and could follow it.
If you have any questions or suggestions please leave a comment below.

# Complexity
- Time complexity:
<!-- Add your time complexity here, e.g. $$O(n)$$ -->
Change: $$O(Log N)$$ Find: $$O(k Log N)$$
- Space complexity:
<!-- Add your space complexity here, e.g. $$O(n)$$ -->
$$O(N)$$
# Code
```cpp []
class NumberContainers {
public:
    unordered_map<int, priority_queue<int, vector<int>, greater<>>> ntoi;
    unordered_map<int, int> iton;
    NumberContainers() {
        
    }
    
    void change(int index, int number) {
        iton[index] = number;
        if(ntoi.find(number) != ntoi.end()){
            ntoi[number].push(index);
        } else{
            priority_queue<int, vector<int>, greater<>> pq;
            pq.push(index);
            ntoi[number] = pq;
        }
    }
    
    int find(int number) {
        if(ntoi.find(number) != ntoi.end()) {
            priority_queue<int, vector<int>, greater<>> pq = ntoi[number];
            while(!pq.empty()){
                if(iton[pq.top()] == number){
                    return pq.top();
                }
                pq.pop();
            }
        }
        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);
 */
```
['Hash Table', 'Design', 'Heap (Priority Queue)', 'Ordered Set', 'C++']