Topics › Basics › Patterns

Pattern 19

Easy TUF ID 411 A2Z

Problem

Given a positive integer n, print the symmetric void: 2n rows, each 2n characters wide. The first row is solid stars. Each following row of the top half removes one star from the inner end of both sides, so a gap opens in the middle and grows by two per row, until the n-th row has a single star at each edge. The bottom half is the top half upside down, so the whole figure is symmetric about its horizontal midline.

Constraints: 1 ≤ n ≤ 50 or so; the output has 4n^2 characters.

Example 1

n = 3
******
**  **
*    *
*    *
**  **
******

Six rows of six characters; the gap grows 0, 2, 4 and then shrinks 4, 2, 0.

Example 2

n = 5
**********
****  ****
***    ***
**      **
*        *
*        *
**      **
***    ***
****  ****
**********

Rows 5 and 6 are identical, which is what makes the figure mirror-symmetric with an even number of rows.

Reading the pattern

Each row consists of s stars, a gap, and s stars again. Because the width is always 2n, the gap is forced: gap = 2n - 2s = 2(n - s). So a row is completely determined by its star count s, and the pattern is just the sequence of star counts

n, n-1, ..., 2, 1, 1, 2, ..., n-1, n

for rows 0 .. 2n-1. Written as a formula over the row index r (0-based):

Everything else is bookkeeping. You can implement the two halves as two separate loops that mirror each other, or as one loop over all 2n rows using the formula above. Both are shown. Both return the finished picture as a single String (newline after every row) so main can compare them with expected strings and check structural properties, such as every row being a palindrome, for n up to 20.

Approach 1: Two halves, three loops per row

Intuition. Translate the description literally. For the top half, row i (0-based) has n - i stars on each side and 2i spaces in between. For the bottom half, row i has i + 1 stars on each side and 2(n - i - 1) spaces. Each half is a loop with three inner loops: stars, spaces, stars.

Algorithm.

  1. For i from 0 to n - 1: append n - i stars, 2i spaces, n - i stars, newline.
  2. For i from 0 to n - 1: append i + 1 stars, 2(n - i - 1) spaces, i + 1 stars, newline.
static String nestedLoops(int n) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < n; i++) {                       // top half: n-i stars each side, 2i spaces
        for (int j = 0; j < n - i; j++) sb.append('*');
        for (int j = 0; j < 2 * i; j++) sb.append(' ');
        for (int j = 0; j < n - i; j++) sb.append('*');
        sb.append('\n');
    }
    for (int i = 0; i < n; i++) {                       // bottom half: i+1 stars each side, 2(n-i-1) spaces
        for (int j = 0; j < i + 1; j++) sb.append('*');
        for (int j = 0; j < 2 * (n - i - 1); j++) sb.append(' ');
        for (int j = 0; j < i + 1; j++) sb.append('*');
        sb.append('\n');
    }
    return sb.toString();
}

Complexity. Time O(n^2): 2n rows of 2n characters, each appended in constant time. Space O(n^2) for the output; no other memory grows with n.

The duplicated structure is a hint that there is a shorter formulation, but the two-loop version is still worth knowing: when a pattern’s halves follow different rules, two loops is the honest way to write it.

Approach 2: One loop with a star-count formula

Intuition. Compute the star count s for row r with the two-case formula from the analysis, then build the row from three pieces with String.repeat: s stars, 2(n - s) spaces, s stars. The gap is derived from s, so it is impossible for the row width to come out wrong.

Algorithm.

  1. For r from 0 to 2n - 1: let s = (r < n) ? n - r : r - n + 1.
  2. Let side = "*".repeat(s).
  3. Append side, then " ".repeat(2(n - s)), then side, then a newline.
static String formula(int n) {
    StringBuilder sb = new StringBuilder();
    for (int r = 0; r < 2 * n; r++) {
        int stars = r < n ? n - r : r - n + 1;          // n, n-1, ..., 1, 1, ..., n-1, n
        String side = "*".repeat(stars);
        sb.append(side).append(" ".repeat(2 * (n - stars))).append(side).append('\n');
    }
    return sb.toString();
}

Dry run for n = 3:

r r < n? stars gap row
0 yes 3 0 ******
1 yes 2 2 ** **
2 yes 1 4 * *
3 no 1 4 * *
4 no 2 2 ** **
5 no 3 0 ******

Complexity. Time O(n^2): each row is built from three repeat calls whose lengths add up to 2n. Space O(n^2) for the output plus O(n) of temporary strings per row.

A note on the symmetry: for r ≥ n the star count is r - n + 1, and for the mirror row 2n - 1 - r (which is < n) it is n - (2n - 1 - r) = r - n + 1 as well. That algebra is exactly why rows r and 2n - 1 - r are identical, and it is what the tests check for every n.

Edge cases and pitfalls