Problem overview
The function printStars receives a positive integer n and prints a triangle of stars. It has no return value: its job is the output. Line number i (counting from 1) holds i stars, so the triangle grows by one star per line.
For n = 5 the output is:
*
**
***
****
*****
Approach: each row is the previous row plus one star
There are two ways to think about a row. You can build it from scratch each time, with an inner loop that prints i stars. Or you can notice that row 3 is just row 2 with a star added at the end. The second view needs no inner loop: keep one string, add a star, print it, and repeat.
Following n = 3: the string starts empty. After the first pass it is "*" and gets printed. After the second pass it is "**", and after the third "***". Each pass prints one line, so n passes print n lines.
Step by step
- Declare
stras an emptyvar. It holds the current row. It must be avarbecause the loop gives it a new value on every pass. - Loop once per row.
for (i in 0 until n)runs the body exactlyntimes, sinceuntilexcludes its upper bound. The counterionly counts the passes; the body never reads it. - Add a star.
str += "*"makes a new string, the old one plus a star, and stores it back instr. Strings in Kotlin can't be edited, so+=replaces the whole value. - Print the row.
println(str)writes the string and ends the line. It sits inside the loop, after the star was added, so each pass prints the row it just extended.
The solution in Kotlin
class Solution {
fun printStars(n: Int) {
var str = ""
for (i in 0 until n) {
str += "*"
println(str)
}
}
}
Kotlin details worth knowing:
printlnversusprint.printlnadds a line break after the text, andprintdoesn't. Usingprinthere would put every star on one long line.0 until nversus1..n.0 until ngives0, 1, ..., n - 1, and1..ngives1, 2, ..., n. Both runntimes. The first is the usual choice when the counter isn't used.- An unused loop variable. Kotlin accepts it. An underscore is not allowed as a loop variable name in a
forloop (the compiler reports that the name is reserved), so the variable keeps a real name.repeat(n) { ... }is an alternative that needs no counter. - The return type. A function without a declared return type returns
Unit, Kotlin's counterpart ofvoid. Nothing is returned, only printed.
Complexity
Let n be the input.
Time: O(n^2). Row i has i stars, and both appending and printing cost time proportional to the row length. Altogether the program handles 1 + 2 + ... + n = n(n + 1) / 2 stars. That is the size of the output itself, so no solution can do better than O(n^2).
Space: O(n). The only extra data is the current row, which has at most n stars.
Edge cases and common mistakes
n = 1. One pass, one line:*.- Printing outside the loop. After the loop,
strholds the longest row only, so the output would be a single line ofnstars. - Declaring
strinside the loop. Each pass would start from an empty string, and every line would be a single star. - Adding the star after printing. The first line would be empty, and the last row would never print, so the triangle would be shifted by one.
- Using
valforstr.str += "*"then fails to compile, because avalcannot be reassigned. - Off by one.
0 until n - 1prints one row too few, and0..nprints one too many.
Testing
n = 1prints a single*.n = 3prints*,**,***on three lines.n = 5prints the triangle shown above, five lines in total.