Problem overview
The method printStars takes a positive Int named n and prints a triangle of stars. Row 1 has one star, row 2 has two, and so on up to row n, which has n stars. The method returns nothing; its job is the printed output. For n = 5 the output is:
*
**
***
****
*****
Approach: grow one row into the next
Look at how consecutive rows relate. Each row is the previous row with one more star at the end. That suggests a loop that keeps the current row in a string variable, adds a star to it, and prints it. After n passes, n rows have been printed and each is one character longer than the one before.
No row has to be built from scratch, and there is no inner loop to count stars. The string carries the previous row with it.
Step by step
- Declare the row. Create a
varnamedstrset to the empty string"". It is avarbecause it changes in every pass. - Loop once per row with
for (i <- 0 until n). The range0 until nexcludes its upper bound, so it produces exactlynvalues. The variableionly counts the rows and is never used in the body. - Add a star to the end of
strwith+=. On the first pass the string holds one star, on the second pass two, and so on. - Print the row with
println(str), still inside the loop. Eachprintlnends with a newline, so every row gets its own line. Printing after the loop would show only the last, longest row.
The solution in Scala
class Solution {
def printStars(n: Int): Unit = {
var str = ""
for (i <- 0 until n) {
str += "*"
println(str)
}
}
}
The Scala details worth knowing:
untilversusto.0 until 5covers 0, 1, 2, 3, 4 and stops before 5.1 to 5covers 1 to 5 inclusive. Both give five iterations, so either works here, because the loop variable isn't used.- The result type
Unit.Unitis Scala's "no useful value" type, similar tovoidin other languages. The method runs for its side effect, printing. +=on a string. Strings can't be modified, sostr += "*"builds a new string and stores it instr, which is whystrmust be avar. Avalwould not compile with+=.printlnversusprint.printlnadds a line break after the text.printdoesn't, and using it would run all the rows into one line, such as******for three rows' worth of stars.- An alternative. Scala can repeat a string with
*, so"*" * iisistars. A loopfor (i <- 1 to n) println("*" * i)prints the same triangle. The lesson's version shows how a value is built up from one iteration to the next.
Complexity
Row k has k stars, so printing all rows writes 1 + 2 + ... + n = n(n + 1) / 2 characters. The output alone makes the time O(n^2). The string str reaches length n, so the extra space is O(n). Each += copies the current row, which is within the same quadratic total.
Edge cases and common mistakes
n = 1. One pass, one row with one star.n = 0or negative. The task saysnis positive, but for these values the range is empty, nothing is printed and the method returns normally.- Printing outside the loop. Only one row appears.
- Resetting
strinside the loop. If the declaration moves into the loop body, every row has just one star. - Off-by-one ranges.
0 until n - 1prints one row too few, and0 to nprints one too many. - Using
print. Without the line break, the rows run together.
Testing
n = 1prints one line:*.n = 3prints*,**and***on three lines.n = 5prints the five-row triangle shown above.
