Problem overview
The method addContact gets phoneBook, an unordered_map<string, string> from names to phone numbers, plus a name and a phone number. It adds the name with its number and returns the phone book. But a name that is already in the book keeps its old number: only new names are added. The order of the entries does not matter.
With {"Ana": "555-0142", "Ben": "555-0199"} and "Cara" with "555-0123", Cara is added. With "Ben" and "555-0100", nothing changes, and Ben keeps "555-0199". With an empty book and "Max", the book gets one entry.
Approach
Assigning with phoneBook[name] = number adds a missing key, but it also overwrites the value of an existing one. The task forbids the overwrite, so you must check first. phoneBook.count(name) is 0 when the name is not a key, and 1 when it is. Add the contact only in the 0 case.
Step by step
- Write an
ifthat checksphoneBook.count(name) == 0, and write its closing brace right away. - Inside it, store the number under the name:
phoneBook[name] = number. The key is new, so assigning adds it with its value. - After the
if, returnphoneBook. It either has the new contact, or it is as it was.
The solution in C++
class Solution {
public:
unordered_map<string, string> addContact(unordered_map<string, string>& phoneBook, string name, string number) {
if (phoneBook.count(name) == 0) {
phoneBook[name] = number;
}
return phoneBook;
}
};
An unordered_map has no fixed order, so a program that prints it may list the entries in any order. To compare results, sort them by key first. Running the method on the statement's examples, with entries printed as name: number lines sorted by name, gives:
Ana: 555-0142
Ben: 555-0199
Cara: 555-0123
For the second example, the book stays at two entries, Ana: 555-0142 and Ben: 555-0199. For the third, an empty book plus Max gives the single entry Max: 555-0100.
Trying more inputs
Add "Zoe" with "555-0111" to an empty book, then add "Zoe" again with "555-0222". The second call changes nothing, so Zoe keeps 555-0111. Then add "Yan" with the same number "555-0111". Both people are in the book, because two names may share a number. The final book has the entries Yan: 555-0111 and Zoe: 555-0111.
The method changes the book you pass in, because the parameter is a reference, and it also returns a copy of it. Both have the same contents, so checking either one is fine. Keeping the check and the store in the method, rather than in the caller, means every caller gets the same rule: existing names are never overwritten.
Complexity
Time is O(1) on average for the lookup and the insert, since a hash map does not scan its entries. Space is O(1) extra.
Edge cases and common mistakes
- Skipping the check. Writing
phoneBook[name] = numberwithout theifreplaces Ben's number with"555-0100", which breaks the second example. - Checking the number instead of the name. Two people may share a number. Only the name matters, because the name is the key.
- Wrong comparison.
count(name) > 0inside theifwould add only names that exist already. - Empty book. No special case is needed:
counton an empty map is 0, so the contact is added.
