Problem overview
The method printRhombus receives an odd positive integer n and prints a rhombus (a diamond) of stars. It prints n lines, and every line is exactly n characters wide, so the lines of stars are padded with spaces on both sides. The trailing spaces count: the line * has two spaces after the star.
For n = 5 the output is the following. Here each space is shown as a dot so that you can see the padding:
..*..
.***.
*****
.***.
..*..
The widths of the star runs are 1, 3, 5, 3, 1. The padding on each side is 2, 1, 0, 1, 2.
Approach: track two numbers per line
Every line has the same shape: some spaces, some stars, the same number of spaces again. So a line is described by two numbers, stars and spaces (the padding on each side), and stars + 2 * spaces always equals n.
The first line has one star and Math.floor(n / 2) spaces per side. In the top half, each line adds two stars and takes away one space on each side. After the middle line, each line does the opposite. The middle line is the widest, with n stars and no padding.
Building a run of the same character many times is a job of its own, so the lesson pulls it out into a helper, buildString(n, character). The main method then reads almost like the shape: left padding, stars, right padding.
Step by step
The lesson writes printRhombus first, assuming the helper exists.
- Start with one star. Declare
starswithletas anumber, set to 1. - Compute the padding. Declare
spacesthe same way, set toMath.floor(n / 2). Forn = 5the division gives 2.5 because/keeps the fraction, andMath.floorrounds it down to 2. - Loop over the lines. Write
for (let i = 0; i < n; i++), one pass per printed line. - Build and print each line. Inside the loop, declare
stras the left spaces, plus the stars, plus the right spaces, each made withthis.buildStringand joined with+. Print it withconsole.log. Both space runs are needed so that the line is exactlyncharacters long. - Update for the next line. Still inside the loop, after printing, check
i < Math.floor(n / 2). In the top half, add 2 tostarsand subtract 1 fromspaces. Otherwise, subtract 2 fromstarsand add 1 tospaces. The middle line, whereiequalsMath.floor(n / 2), takes theelsebranch, so the shape starts to narrow right after it.
Then the helper, written above printRhombus inside the class:
- Declare it with parameters
n: numberandcharacter: string, returning astring. TypeScript has no separate character type, so the character is a string of length one. - Build the run. Declare
stras an empty string, loopntimes appendingcharacterwith+=, and returnstr.
The solution in TypeScript
class Solution {
buildString(n: number, character: string): string {
let str: string = "";
for (let i = 0; i < n; i++) {
str += character;
}
return str;
}
printRhombus(n: number): void {
let stars: number = 1;
let spaces: number = Math.floor(n / 2);
for (let i = 0; i < n; i++) {
let str: string =
this.buildString(spaces, " ") +
this.buildString(stars, "*") +
this.buildString(spaces, " ");
console.log(str);
if (i < Math.floor(n / 2)) {
stars += 2;
spaces -= 1;
} else {
stars -= 2;
spaces += 1;
}
}
}
}
The TypeScript details worth a closer look:
- Methods call each other through
this. InsideprintRhombus, a barebuildString(...)would not be found.this.buildString(...)calls the method on the same object. - The expression continues on the next line. The lines of the assignment end with
+, so TypeScript knows the expression isn't finished. Putting the+at the start of the next line works too. - Two variables named
strandi. The helper and the main method each have their own. Variables declared withletlive only in the block or method where they appear, so they don't clash. - No integer division.
numberis a floating-point type, so5 / 2is2.5.Math.floor(n / 2)gives the whole-number half. Without it,spaceswould be 2.5 and the helper would run its loop three times for it. "*"and" "are strings. Single and double quotes work the same, so' 'and'*'are equally valid.- Built-in alternative.
" ".repeat(spaces)does the job ofbuildString. The lesson writes the helper by hand to practise loops and methods.
Complexity
Time: O(n²). There are n lines, and each line is built in O(n) time, because the helper loops over a total of exactly n characters. The output itself has about n² characters, so no solution can be faster.
Space: O(n). At any moment, the program holds one line of n characters, plus a few numbers.
Edge cases and common mistakes
n = 1. One pass prints a single*. The values ofstarsandspacesafter the update are not used.n = 3. The output is.*.,***,.*., with dots standing for spaces.- Forgetting the right padding. The lines come out shorter than
n, and the output no longer matches the expected text. - Updating before printing. The first line would already have three stars.
- Using
i <= Math.floor(n / 2)for the widening. The middle line would still widen the next line, which would get 7 stars whennis 5, more than the width. - Forgetting
Math.floor. With fractional spaces the output for any oddnis wrong. - Even
n. The statement promises an odd number. For an even one there is no single middle line, and this code would print a lopsided shape that is wider thann.
Testing
n = 1prints*.n = 3prints three lines: one star with a space on each side, then***, then the first line again.n = 5prints the rhombus from the example, and each line is 5 characters long.