Problem overview
The method getFullNames(names: Array[String]) receives an array in which every first name is directly followed by its last name. It returns a List[String] with one full name per pair, joined by a single space.
For ["John", "Doe", "Andy", "Smith", "Mary", "Johnson"] the pairs are John Doe, Andy Smith and Mary Johnson, so the result is List(John Doe, Andy Smith, Mary Johnson). Six names produce three full names.
Approach
First names sit at the even indices 0, 2, 4, and so on, and each last name sits right after its first name, at i + 1. So the loop does not need to visit every index: it visits only the even ones, and at each stop it joins names(i) and names(i + 1). In Scala that is a range with a step: 0 until names.size by 2.
The results have to be collected somewhere. The array's size is fixed and the final count (half the input) is known, but a growable buffer is the simplest tool, and the method converts it to the required List at the end.
Step by step
- Create an empty
ArrayBuffer[String]. It is a mutable, growable sequence. The full pathscala.collection.mutable.ArrayBufferavoids an import. The nameanswercan be aval, because the variable never points to another buffer, even though the buffer's contents change. - Loop over the even indices.
for (i <- 0 until names.size by 2)produces 0, 2, 4, ... Theby 2sets the step, anduntilexcludes the end, so for six namesiis 0, 2 and 4. - Build one full name.
names(i) + " " + names(i + 1)joins the first name, a space and the last name. - Append it.
answer += nameadds the string to the end of the buffer, which keeps the pairs in input order. - Convert and return after the loop.
answer.toListcopies the buffer into an immutableList, the type in the method's signature. Returning inside the loop would end it after the first pair.
The solution in Scala
class Solution {
def getFullNames(names: Array[String]): List[String] = {
val answer = scala.collection.mutable.ArrayBuffer[String]()
for (i <- 0 until names.size by 2) {
val name = names(i) + " " + names(i + 1)
answer += name
}
return answer.toList
}
}
Some Scala details:
- Ranges with a step.
0 until 6 by 2is the range 0, 2, 4.0 to 6 by 2would also include 6, which would be one step too far for this problem. - Arrays use parentheses.
names(i)reads an element. In Scala, indexing is a method call (apply), so there are no square brackets. valwith a mutable object.val answercannot be reassigned, butanswer += namecalls a method on the same buffer, so it still works. (With avarand an immutableList, you would writeanswer = answer :+ name, which copies the list on every append.)sizeandlength. On anArrayboth give the number of elements.- Immutable result. A
Listcannot be changed after it is built, so the caller cannot accidentally modify the answer through the buffer.
Complexity
Let n be the length of names.
Time: O(n). The loop runs n / 2 times. Each pass joins two short strings and appends to the buffer in amortized constant time. toList then copies the n / 2 results once.
Space: O(n). The buffer and the list hold n / 2 strings each. The strings themselves are new, because each full name is a fresh string.
Edge cases and common mistakes
- Empty array.
0 until 0 by 2is empty, so the method returns an empty list. - Odd length. The statement guarantees pairs, so the length is even. With an odd length, the last index
iwould makenames(i + 1)fail with anArrayIndexOutOfBoundsException. For["A", "B", "C"]the method throws on the second pass. - Stepping by 1. Looping over every index would pair
DoewithAndyand produce six strings, not three. - Missing space. The separator must be exactly one space:
"John" + "Doe"givesJohnDoe. - Returning the buffer. An
ArrayBufferis not aList, so the method needstoListto satisfy its declared return type.
Testing
Array("John", "Doe", "Andy", "Smith", "Mary", "Johnson")givesList(John Doe, Andy Smith, Mary Johnson).Array("A", "B", "C", "D")givesList(A B, C D).Array()givesList().
