Problem overview
oldestPet receives a vector of pets. Each pet is a pair<string, int>: a name and an age, like {"Rex", 4}. The function returns the name of the oldest pet. When several pets share the oldest age, the one that comes first in the vector wins.
For [("Rex", 4), ("Bella", 7), ("Max", 2)] the answer is "Bella". For [("Luna", 3), ("Coco", 9), ("Milo", 9)] it is "Coco", because Coco and Milo are both 9 and Coco is listed first. For a single pet, [("Kiki", 0)], it is "Kiki".
Approach: keep the best pair so far
This is the usual "find the largest" loop, with one twist: the thing being compared (the age) is only part of what is kept. Store the whole pair for the oldest pet so far. Then the name comes along with its age, and nothing has to be looked up later.
Start with pets[0], since the first pet is the oldest you have seen before the loop looks at the others. Then compare each pet's age, pet.second, with the oldest one's age. Only a strictly larger age replaces the pair. On a tie, nothing changes, so the earlier pet stays, which is exactly the tie rule.
Step by step
- Declare
oldestas apair<string, int>and set it topets[0]. - Loop over
petswith a range-basedfor, naming each pairpet. - Compare ages. The age is the pair's
second, so testpet.second > oldest.second. Use>, not>=. - Replace the whole pair:
oldest = pet;. - Return the name,
oldest.first, after the loop. The function returns only the name, not the pair.
The solution in C++
class Solution {
public:
string oldestPet(vector<pair<string, int>>& pets) {
pair<string, int> oldest = pets[0];
for (pair<string, int> pet : pets) {
if (pet.second > oldest.second) {
oldest = pet;
}
}
return oldest.first;
}
};
Two C++ details are worth knowing:
- Pairs are copied.
pair<string, int> oldest = pets[0];and the loop variablepetare copies of the vector's pairs. That is fine here, and changingoldestnever changes the vector. For a large vector of big values you could writeconst auto& petto avoid the copies. - The vector is passed by reference (
&) so the call doesn't copy the whole vector.
Following the second example
For [("Luna", 3), ("Coco", 9), ("Milo", 9)], oldest starts as Luna, age 3. Luna is compared with herself and nothing changes. Coco's 9 is larger than 3, so oldest becomes Coco. Milo's 9 is not larger than Coco's 9, so Coco stays and the function returns "Coco".
Edge cases and common mistakes
- Using
>=. With("Luna", 3), ("Coco", 9), ("Milo", 9)that would replace Coco with Milo and return"Milo". - Comparing the wrong member.
pet.first > oldest.firstcompares names alphabetically, not ages, and still compiles. - Starting with an empty name and age 0. For
[("Kiki", 0)]nothing is older than 0, so the function would return an empty string. Start frompets[0]. - Returning the pair. The return type is
string, so returnoldest.first. - One pet.
[("Kiki", 0)]returns"Kiki": no later pet is older.
The same loop for any best-so-far problem
The shape of this code is reusable: start with the first item, visit every item, replace the best one only when the new item beats it strictly, and return what you need from the best one at the end. The strict comparison is the part that decides ties in favour of the earlier item.
Testing
[("Rex", 4), ("Bella", 7), ("Max", 2)]givesBella.[("Luna", 3), ("Coco", 9), ("Milo", 9)]givesCoco.[("Kiki", 0)]givesKiki.
