Usually, when you need to find elements by quality A (value), as well as by quality B (insertion order), then you start looking for a data structure that actually has two data structures inside each other’s link, or else alternating .
For example: two cards whose keys are quality A and quality B, which values are a common pointer to a structure containing iterators, to both cards and a value. Then you have log (n) to find the element through any quality, and erase ~ O (logn) to remove two iterators from any of the maps.
struct hybrid { struct value { std::map<std::string, std::shared_ptr<value>>::iterator name_iter; std::map<int, std::shared_ptr<value>>::iterator height_iter; mountain value; }; std::map<std::string, std::shared_ptr<value>> name_map; std::map<int, std::shared_ptr<value>> height_map; mountain& find_by_name(std::string s) {return name_map[s]->value;} mountain& find_by_height(int height h) {return height_map[s]->value;} void erase_by_name(std::string s) { value& v = name_map[s]; name_map.erase(v.name_iter); height_iter.erase(v.height_iter);
However, in your case, you can do even better than this O (logn), since you only need the “latest” and “highest”. To quickly perform pop-height, you need a quick way to determine the next maximum, which means it needs to be calculated beforehand when pasting. To find the height position relative to the rest, you need some kind of map. To quickly pop, you need a quick way to find the next, last, but trivially calculated. I would recommend creating a map or a bunch of nodes, where the keys are the value to find max and the values are a pointer to the next last value. This gives you an embedding of O (logn), O (1) to find the latest, O (1) or O (logn) to find the maximum value (depending on implementation) and erasing ~ O (logn) using any index.
source share