Problem overview
The method getFullNames receives two arrays of strings, firstNames and lastNames. The name at position i in one array belongs with the name at position i in the other. The method returns a new array of full names, each first name and last name joined by a single space, in the original order.
For firstNames = ["John", "Andy", "Mary"] and lastNames = ["Doe", "Smith", "Johnson"], the result is ["John Doe", "Andy Smith", "Mary Johnson"].
Approach: walk both arrays with one index
A for...of loop would visit the elements of one array, but it can't tell you which position you are at, so it can't reach the matching element of the other array. An index loop solves that: one variable i addresses firstNames[i] and lastNames[i] in the same iteration.
The plan is to build a result array, add one full name per iteration, and return the array when the loop ends.
Step by step
- Create the result array. Declare an empty
string[]callednames. It collects the answer, so it has to exist before the loop starts. - Loop over the indices of
firstNames. Startiat 0 and continue whilei < firstNames.length. The index is what links each first name to its last name. - Build one full name. Inside the loop, join
firstNames[i], a single space" "andlastNames[i]with+. The space in the middle is part of the required format. - Add it to the result.
names.push(name)appends the string to the end of the array, so the order of the input is kept. - Return after the loop. Only when the loop is finished does
nameshold every full name, so thereturngoes below the loop and not inside it.
The solution in TypeScript
class Solution {
getFullNames(firstNames: string[], lastNames: string[]): string[] {
let names: string[] = [];
for (let i = 0; i < firstNames.length; i++) {
const name: string = firstNames[i] + " " + lastNames[i];
names.push(name);
}
return names;
}
}
Some details of the code:
letandconst.namesis declared withlet, although it is never reassigned.constwould work too, becausepushchanges the array's contents and not the variable.nameis aconstbecause each iteration creates it once and never changes it.- Annotations are for the compiler.
string[]and: stringtell TypeScript what the variables may hold. They are erased when the code is compiled to JavaScript and add no checks at run time. - Joining with
+. When one operand is a string,+joins instead of adding. A template literal does the same job:`${firstNames[i]} ${lastNames[i]}`. - Each full name is a new string. Strings in TypeScript can't be changed in place, and the input arrays are left untouched.
Complexity
Let n be the number of names. Time: O(n). The loop runs n times and each iteration joins two strings and pushes one element. Joining depends on how long the names are, but for ordinary names that is a small constant.
Space: O(n). The output array holds n strings. Apart from the output, the method only uses the index and one temporary string.
Edge cases and common mistakes
- Empty arrays. The loop does not run and the method returns
[]. - Forgetting the space.
firstNames[i] + lastNames[i]gives"JohnDoe". - Arrays of different lengths. The problem expects equal lengths. If
lastNameswere shorter,lastNames[i]would beundefinedpast its end, and the text would become"B undefined"with no error. IffirstNameswere shorter, the extra last names would simply be ignored. - Returning inside the loop. A
returnin the loop body ends the method after the first name, giving a one-element array. - Declaring
namesinside the loop. Each iteration would start with a new empty array, and the variable would not exist after the loop. - Using
<=in the loop condition. The last index isfirstNames.length - 1. Going one further readsundefinedfrom both arrays and adds"undefined undefined".
Testing
["John", "Andy", "Mary"]and["Doe", "Smith", "Johnson"]give["John Doe", "Andy Smith", "Mary Johnson"].[]and[]give[].["Ada"]and["Lovelace"]give["Ada Lovelace"].