Problem overview
The function printRhombus receives an odd positive integer n and prints a rhombus of stars made of n lines. Every line is exactly n characters wide, including the spaces on the right. Each line is the stars centred between spaces.
For n = 5 the lines are, with a vertical bar marking where each line ends:
* |
*** |
*****|
*** |
* |
The rows hold 1, 3, 5, 3 and 1 stars, with 2, 1, 0, 1 and 2 spaces on each side. The trailing spaces are part of the required output.
Approach: two counters that change in step
Every line is built from the same three parts: some spaces, some stars, the same number of spaces. Only the counts change. Going down the top half, each line gains one star on each side, so the star count grows by 2 while the spaces on each side shrink by 1. In the bottom half it is the reverse. Since the widest line is the middle one, the middle line index is n / 2, and the first line starts with n / 2 spaces on each side and a single star.
That gives a plan with two variables, stars and spaces, and one loop over the lines. Each pass prints a line from the current counts, then updates the counts for the next line. A small helper that repeats a character n times keeps the printing code short.
Step by step
- Start with one star.
var stars = 1is the star count of the first line. It is avar, since it changes every line. - Start with
n / 2spaces.var spaces = n / 2counts the spaces on each side of the stars. Dividing twoIntvalues drops the remainder, so5 / 2is 2. - Loop over the lines.
for (i in 0 until n)runs once per line. The indexiis needed to know which half of the rhombus the line is in. - Build and print the line. Take the left spaces, the stars, then the right spaces, join them with
+and print the result withprintln. The right-hand spaces are required so that every line hasncharacters. The helperbuildString(n, character)makes each part. - Update the counts. While
i < n / 2, the rhombus is still widening: add 2 tostarsand subtract 1 fromspaces. Otherwise it narrows: subtract 2 and add 1. The middle line hasi == n / 2, so it goes to theelsebranch, and the shrinking starts right after it. - Write the helper.
buildString(n: Int, character: Char): Stringstarts with an emptyvarstring, appendscharacterin a loop ofnpasses and returns the result. One helper serves both spaces and stars.
The solution in Kotlin
class Solution {
fun buildString(n: Int, character: Char): String {
var str = ""
for (i in 0 until n) {
str += character
}
return str
}
fun printRhombus(n: Int) {
var stars = 1
var spaces = n / 2
for (i in 0 until n) {
val str = buildString(spaces, ' ') +
buildString(stars, '*') +
buildString(spaces, ' ')
println(str)
if (i < n / 2) {
stars += 2
spaces -= 1
} else {
stars -= 2
spaces += 1
}
}
}
}
Kotlin details worth knowing:
- A
+at the end of a line. Kotlin ends a statement at the end of a line, unless the line can't be complete. A line that ends with+expects more, so the expression continues on the next line. If the+were at the start of the next line, Kotlin would read that line as a separate statement with a unary plus, and the code would not compile. CharandString.' 'and'*'in single quotes areCharvalues, matching the helper'scharacter: Charparameter.str += characterappends one character to the string.- Integer division.
n / 2is anIntand drops the fraction. For oddnit is the exact number of spaces beside the middle line. - The helper's name. Kotlin's standard library also has a function called
buildString. A member function of the class with the same name takes priority inside the class, so the lesson's version is the one called. - A shorter helper. The standard library's
" ".repeat(n)does the same job. The hand-written loop practises the same idea.
Complexity
Time: O(n^2). The program prints n lines of n characters each, so the output has n * n characters. No approach can beat that. Building a line with the helper copies the growing string on every append, which makes it a little more than linear in the line length, but the line is only n characters long.
Space: O(n). At most one line, with n characters, is built at a time.
Edge cases and common mistakes
n = 1.spacesstarts at 0, the loop runs once, and the output is a single*. The update afterwards runs once too and produces counts that are never used.- Missing right-hand spaces. The lines would be shorter than
ncharacters. The statement requires the trailing spaces. - Using
i <= n / 2. The middle line would still widen the counts, so forn = 5the lines would hold 1, 3, 5, 7 and 5 stars. - Changing the counts before printing. The first line would already be widened.
- Using
valforstarsorspaces. They are reassigned inside the loop, so the code wouldn't compile.
Testing
n = 1prints*.n = 3prints*,***,*on three lines, each 3 characters wide.n = 5prints the shape above.