Problem overview
The function oldestPet receives an array pets. Each pet is a tuple (name: String, age: Int). It returns the name of the oldest pet. When several pets share the oldest age, the one that comes first in the array wins. The array always has at least one pet.
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 first.
Approach
This is a running maximum, like finding the largest number in an array, except that the value kept is the whole pair. Start with the first pet as the oldest so far. Then look at each pet: if it is older than the one you keep, keep it instead. At the end, return the kept pet's name.
The tie rule comes from the comparison. With a strict "older than" (>), a pet of the same age doesn't replace the current one, so on a tie the first pet stays. Writing >= would make the last pet of the oldest age win, which is wrong here.
Here is the loop on the second example. The table shows which pet is kept as oldest after each one is handled.
| pet | oldest after this pet |
|---|---|
| Luna | Luna |
| Coco | Coco |
| Milo | Coco |
Coco (9) is older than Luna (3), so Coco replaces her. Milo is also 9, which is not older than 9, so Coco stays. This is the tie rule at work.
Step by step
- Declare
oldestwithvar, starting atpets[0]. The first pet is the oldest you've seen before the loop looks at the others. - Loop over
petswithfor pet in pets. - Compare ages:
pet.age > oldest.age. - Replace the whole pair:
oldest = pet. Keeping the pair brings the name along with the age. - Return
oldest.nameafter the loop. The function returns only the name.
The solution in Swift
class Solution {
func oldestPet(_ pets: [(name: String, age: Int)]) -> String {
var oldest = pets[0]
for pet in pets {
if pet.age > oldest.age {
oldest = pet
}
}
return oldest.name
}
}
Swift details:
- An array of labelled tuples. The parameter type
[(name: String, age: Int)]gives each pair its labels, so inside the looppet.nameandpet.ageread the parts. Callers can pass plain literals such as[("Rex", 4), ("Bella", 7)]. - Tuples are values.
oldest = petcopies the pair. Nothing inpetsis changed. - The first pet is compared with itself. The loop starts at the first element, so
pet.age > oldest.ageis false there. That is harmless.
Edge cases and common mistakes
- One pet.
[("Kiki", 0)]returns"Kiki". - Ties. For Luna 3, Coco 9, Milo 9 the function returns
"Coco". With>=it would return"Milo". - Starting with an age of 0. A pet of age 0 is allowed, and an "oldest age so far" variable starting at 0 would never record such a pet when it is the only one. Starting from
pets[0]avoids this. - Returning the pair or the age. The function must return the name,
oldest.name. - Comparing names.
pet.name > oldest.namecompiles, because strings can be compared, but it finds the alphabetically last name, not the oldest pet. - An empty array.
pets[0]would stop the program with an index-out-of-range error. The constraints promise at least one pet.
Testing
[("Rex", 4), ("Bella", 7), ("Max", 2)]gives"Bella".[("Luna", 3), ("Coco", 9), ("Milo", 9)]gives"Coco".[("Kiki", 0)]gives"Kiki".
