Topics › Basics › Patterns

Pattern 1

Easy TUF ID 401 A2Z

Problem

Given an integer n, print a solid square of stars: n rows, each containing n stars separated by single spaces. This is the first of the classic pattern-printing exercises. Its job is not to be hard; it is to make the two-loop skeleton that every later pattern reuses feel automatic, so that when the shapes get trickier you only have to think about what goes in each cell, never about the loops themselves.

Output format used in this article and in the Java file: every row ends with a newline (including the last one), stars in the same row are separated by exactly one space, and there is no trailing space after the last star. Most judges ignore trailing whitespace, but a precise format is what makes the solutions testable with string equality.

Constraints: 0 ≤ n ≤ 100 is typical. n = 0 prints nothing at all.

Example 1

n = 4

* * * *
* * * *
* * * *
* * * *

Four rows and four columns: n controls both dimensions.

Example 2

n = 1

*

A single cell, so there is no separator anywhere.

How to read any pattern

Before any code, settle four things. First, count the rows: that is the outer loop. Second, for one row, count the columns: that is the inner loop, and its bound may depend on the row index. Third, decide what belongs in cell (i, j): a star, a space, a digit, a letter. Fourth, end every row with a newline. For this pattern the answers are n, n, “always a star” and “yes”, so the inner bound does not depend on the outer index yet. That independence is exactly what makes it the warm-up.

All approaches below return the pattern as a String instead of printing character by character. Returning a string keeps the code testable (main compares it to an expected literal) and the caller prints it with a single System.out.print.

Approach 1: Nested loops

Intuition. Rows are the outer loop and columns are the inner loop. Inside the inner loop we emit one cell. The only subtlety is the separator: a space belongs between two stars, not after every star, so we emit a space before each star except the first in its row. That “fencepost” check is the standard way to avoid trailing spaces.

Algorithm.

  1. Create a StringBuilder.
  2. For i from 0 to n - 1 (rows):
  3. For j from 0 to n - 1 (columns): if j > 0 append a space, then append *.
  4. After the inner loop append \n.
  5. Return the built string.
static String nestedLoops(int n) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (j > 0) sb.append(' ');
            sb.append('*');
        }
        sb.append('\n');
    }
    return sb.toString();
}

Complexity. Time O(n^2): there are n^2 cells and each costs constant time. Space O(n^2) for the output itself, which is unavoidable since the answer has that many characters; the extra working memory is O(1).

Approach 2: One loop over the flat index

Intuition. The grid has n * n cells. Number them 0, 1, ..., n*n - 1 row by row. Cell k sits in row k / n and column k % n. With that mapping a single loop can walk the whole grid and still know when a row ends: whenever the column k % n equals n - 1. The output is identical; what changes is where the two-dimensional structure lives, in the arithmetic rather than in a second loop.

This is worth knowing in its own right. The same k / n, k % n mapping is how a 2-D matrix is stored in a 1-D array, and it reappears in problems such as binary search over a sorted matrix, where you treat the matrix as one long sorted list.

Algorithm.

  1. For k from 0 to n*n - 1: compute j = k % n.
  2. If j > 0 append a space; append *.
  3. If j == n - 1, the row is complete, so append \n.
static String singleLoop(int n) {
    StringBuilder sb = new StringBuilder();
    for (int k = 0; k < n * n; k++) {
        int j = k % n;                       // column of cell k (the row would be k / n)
        if (j > 0) sb.append(' ');
        sb.append('*');
        if (j == n - 1) sb.append('\n');     // last column: close the row
    }
    return sb.toString();
}

Complexity. Time O(n^2), one iteration per cell, with a division and a modulo each, which are constant time. Space O(1) beyond the output.

Note that for n = 0 the loop condition k < 0 is false immediately, so k % n is never evaluated and there is no division by zero.

Approach 3: Build one row, repeat it

Intuition. Every row of this pattern is the same string, "* * ... *". So build that row once and repeat it n times. Collections.nCopies(n, "*") is a list of n stars, String.join(" ", list) glues them with single spaces and no trailing space, and String.repeat(n) stacks n copies of row + "\n". There is no explicit loop at all; the Java library does the iteration.

Algorithm.

  1. row = String.join(" ", Collections.nCopies(n, "*")).
  2. Return (row + "\n").repeat(n).
static String repeatRow(int n) {
    String row = String.join(" ", Collections.nCopies(n, "*"));
    return (row + "\n").repeat(n);
}

Dry run for n = 3:

step value
nCopies(3, "*") ["*", "*", "*"]
join(" ", ...) "* * *"
row + "\n" "* * *\n"
.repeat(3) "* * *\n* * *\n* * *\n"

Complexity. Time O(n^2), dominated by copying the row n times. Space O(n) extra for the single row, plus the output.

For n = 0 this still works without a special case: nCopies(0, "*") is an empty list, join returns "", and "\n".repeat(0) is "", so the result is the empty string, matching the loop versions.

Edge cases and pitfalls