Java Number Triangle Pattern (Bidirectional)

Beginner
7 min read
Updated: Sep 2026
3 programs
Live preview

What Is This Pattern?

A bidirectional number triangle repeats one digit per row while the row length shrinks. Digits rise on early rows, then mirror down on the last rows.

Remember
Rule: for i from 1 to rows,
      repeat val (rows - i + 1) times
      val = i if i < rows - 1, else rows + 1 - i

11111
2222
333
22
1          ← rows = 5

Natural step after Program 24 (centered pyramid) — here the focus is shrinking rows plus an if/else digit map.

How to Solve It

Shrink with j = i..rows; pick the digit with a simple threshold.

MethodIdeaBest for
If/else mapPrint i early; print rows + 1 - i on the last rowsLearning, interviews, exams
Spaced digitsSame loops; print val + " "When you want gaps between repeats

Pseudocode

Pseudocode
for i from 1 to rows:
    if i < rows - 1:
        val = i
    else:
        val = rows + 1 - i
    for j from i to rows:
        print val
    print newline

Cheat sheet

GoalPattern
Walk rowsfor (int i = 1; i <= rows; i++)
Shrink lengthfor (int j = i; j <= rows; j++)
Fixed map (n = 5)if (i < 4) print(i); else print(6 - i);
General mapval = (i < rows - 1) ? i : (rows + 1 - i);
End the rowSystem.out.println();
Spaced digitsSystem.out.print(val + " ");

Printing Numbers vs Starting a New Line

APIEffectUse for
System.out.printStays on the same lineEach repeated digit val
System.out.printlnEnds the current lineAfter the inner loop

Print digits without a newline, then end the row once.

Live Preview

Change the row count and the bidirectional triangle updates instantly.

Whole numbers from 3 to 9 (enough rows for the rise-then-mirror effect). Tap a chip or type a value.

Live result rows = 5 · 15 digits
11111
2222
333
22
1

Worked Walkthrough — rows = 5

Trace each row’s digit, print count, and printed line.

ivalPrintsPrinted row
11 (i < 4)511111
2242222
333333
42 (6 - i)222
51 (6 - i)11

Total digits: 5 + 4 + 3 + 2 + 1 = 15 = n(n + 1) / 2 — that is why time is O(n²).

Java Programs

Three complete programs: fixed rows = 5, Scanner input with a general ternary, and spaced digits. Use View Output to reveal sample results.

Example 1 — Fixed rows = 5

Hard-coded height — shrink with j = i..5; map digits with i < 4.

Java
public class BidirectionalTriangle {
    public static void main(String[] args) {
        for (int i = 1; i <= 5; i++) {
            for (int j = i; j <= 5; j++) {
                if (i < 4)
                    System.out.print(i);
                else
                    System.out.print(6 - i);
            }
            System.out.println();
        }
    }
}

How It Works

1. Outer loop walks rows. i runs from 1 to 5.

2. Inner loop shrinks. j runs from i to 5 — row length is 6 - i.

3. Digit map. If i < 4, repeat i; else repeat 6 - i (so row 4 → 2, row 5 → 1).

When i = 3, print three 3s. When i = 4, print two 2s.

Example 2 — Rows Input

Read rows at runtime. Use a ternary so the digit map works for any height.

Java
import java.util.Scanner;

public class BidirectionalTriangleInput {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("Enter rows: ");
        int rows = sc.nextInt();

        for (int i = 1; i <= rows; i++) {
            int val = (i < rows - 1) ? i : (rows + 1 - i);

            for (int j = i; j <= rows; j++)
                System.out.print(val);

            System.out.println();
        }
        sc.close();
    }
}

How It Works

1. Prompt and read. Ask for a height, then store it with sc.nextInt().

2. General digit map. (i < rows - 1) ? i : (rows + 1 - i) replaces the hard-coded 4 and 6.

3. Safer input tip. Prefer:

Safer input
if (!sc.hasNextInt()) {
    System.out.println("Enter a positive whole number.");
    return;
}
int rows = sc.nextInt();
if (rows < 1) {
    System.out.println("Enter a positive whole number.");
    return;
}

Example 3 — Spaced Digits

Keep rows = 5 but print each digit followed by a space.

Java
public class BidirectionalTriangleSpaced {
    public static void main(String[] args) {
        int rows = 5;

        for (int i = 1; i <= rows; i++) {
            int val = (i < rows - 1) ? i : (rows + 1 - i);

            for (int j = i; j <= rows; j++)
                System.out.print(val + " ");

            System.out.println();
        }
    }
}

How It Works

1. Same map and shrink. Digit choice and j = i..rows match Examples 1 and 2.

2. Only the print changes. print(val + " ") adds a space after each digit.

3. Same shape. Row lengths and bidirectional values are unchanged — only spacing differs.

Edge Cases & Pitfalls

Check these before calling the solution done.

j = 1

No shrink

Starting the inner loop at 1 prints full-width rows. Use j = i so each row is shorter.

Wrong threshold

Missed mirror

Using i < rows instead of i < rows - 1 skips the mirror on the last rows. Prefer the ternary from Example 2.

println inside

Column of digits

If println is inside the inner loop, each digit lands on its own line. Use print for digits; println only after the inner loop.

rows = 1

Single 1

Output is just 1 — a good sanity check.

rows = 2

Smallest triangle

Two rows: 11 and 1 (both use the mirror branch when rows - 1 = 1).

Bad input

Use hasNextInt

nextInt() throws on letters — prefer hasNextInt() and require a positive whole number.

Time and Space Complexity

ProgramTimeExtra space
Bidirectional triangle (Examples 1–3)O(n²)O(1)

Total digit prints: n + (n − 1) + … + 1 = n(n + 1) / 2 — still quadratic in n.

Key Takeaways

  • Rule: shrink with j = i..rows; digit is i early, then rows + 1 - i.
  • Threshold: switch at i < rows - 1 — that creates the bidirectional effect.
  • Break the row: call println only after the inner loop.
  • Complexity: O(n²) time; O(1) extra space.

One line: shrink the row, pick val with a threshold, repeat val, then println().

Frequently Asked Questions

For rows = 5 and i = 5, the condition i < 4 is false, so the program prints 6 − i which becomes 1.
Because the inner loop runs from j = i to rows. As i increases, the inner loop executes fewer times.
Digits rise (1, 2, 3) on early rows then mirror down (2, 1) on the last rows via the rows + 1 − i mapping.
System.out.print(val) repeats the digit on the same line. System.out.println() ends the row after the inner loop finishes.
A single inner loop with a digit mapping keeps the shrinking row logic in one place.
Replace 5 with rows and use val = (i < rows − 1) ? i : (rows + 1 − i). See Example 2.
O(n²) for n rows because total prints are triangular (n + (n−1) + … + 1).
Use sc.hasNextInt() before sc.nextInt(), require rows ≥ 1, and reject non-numeric input — see Example 2 notes.

Did you know?

This pattern prints repeated digits per row. The inner loop runs from j = i to rows, shrinking each row. The row digit is i for the first half, then switches to rows + 1 - i to produce 22 and 1.

Next: Diagonal Asterisk Pattern

Move on to the diagonal asterisk pattern in the Java number-pattern series.

Program 26 tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

12 people found this page helpful