Java Number Triangle Pattern (Left-Shifted)

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

What Is This Pattern?

A left-shifted descending number triangle prints digits from the row start i through rows. Each next row begins one higher, so the line shortens from the left.

Remember
Rule: for i from 1 to rows,
      print j from i to rows (no spaces)

12345
2345
345
45
5          ← rows = 5

The only new idea vs Program 1 is the inner start: j = i instead of always starting at 1. Same nested-loop skeleton, different shape.

How to Solve It

Outer loop picks the start digit; inner loop prints through rows.

MethodIdeaBest for
Nested loopsOuter i, inner j = i..rowsLearning, interviews, exams
StringBuilderAppend digits, then println the rowWhen you want one print per row

Pseudocode

Pseudocode
for i from 1 to rows:
    for j from i to rows:
        print j
    print newline

Cheat sheet

GoalPattern
Pick row startfor (int i = 1; i <= rows; i++)
Print i..rowsfor (int j = i; j <= rows; j++) System.out.print(j);
End the rowSystem.out.println();
Spaced digitsSystem.out.print(j + " ");
One print per rowAppend to StringBuilder, then println(row)
Vs Program 1Here: j = i; Program 1: print 1..i

Printing Numbers vs Starting a New Line

APIEffectUse for
System.out.printStays on the same lineEach digit j
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 left-shifted triangle updates instantly.

Whole numbers from 1 to 12. Tap a chip or type a value — the preview redraws as you go.

Live result rows = 5 · 15 digits
12345
2345
345
45
5

Worked Walkthrough — rows = 4

Trace each row’s start, range, and printed line.

iInner rangeDigitsPrinted row
11..441234
22..43234
33..4234
44..414

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

Java Programs

Three complete programs: fixed rows = 5, Scanner input, and a StringBuilder row builder. Use View Output to reveal sample results.

Example 1 — Fixed rows = 5

Hard-coded height — outer loop picks start i, inner prints i..rows.

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

        for (int i = 1; i <= rows; i++) {
            for (int j = i; j <= rows; j++) {
                System.out.print(j);
            }
            System.out.println();
        }
    }
}

How It Works

1. Outer loop picks the start. i runs from 1 to rows — that value is where each row begins.

2. Inner loop prints the run. j goes from i to rows with System.out.print(j) (no spaces).

3. Break the line. System.out.println() after the inner loop starts the next row.

When i = 3, the inner loop prints 345. When i = 5, it prints just 5.

Example 2 — Rows Input

Read rows at runtime. Prefer hasNextInt() before nextInt() in real apps.

Java
import java.util.Scanner;

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

        for (int i = 1; i <= rows; i++) {
            for (int j = i; j <= rows; j++) {
                System.out.print(j);
            }
            System.out.println();
        }
        sc.close();
    }
}

How It Works

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

2. Same nested-loop core. Only the source of rows changes — the i..rows rule is identical to Example 1.

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 — StringBuilder Row Builder

Append each digit, then print the full row once with println.

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

        for (int i = 1; i <= rows; i++) {
            StringBuilder row = new StringBuilder();
            for (int j = i; j <= rows; j++) {
                row.append(j);
            }
            System.out.println(row);
        }
    }
}

How It Works

1. Same bounds. Outer i and inner j = i..rows match Example 1.

2. Build, then print. row.append(j) collects digits; println(row) prints the whole line.

3. Same shape. Useful when exams want one print per row — loop bounds stay visible either way.

Edge Cases & Pitfalls

Check these before calling the solution done.

j = 1

Wrong start

Starting the inner loop at 1 prints a growing triangle (Program 1 style), not the left-shifted shape. Use j = i.

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.

Missing println

One long line

Omitting println glues every digit onto a single endless line.

rows = 1

Single 1

Output is just 1 — a good sanity check.

rows ≤ 0

Empty output

The outer loop never runs. Validate and require rows ≥ 1.

Bad input

Use hasNextInt

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

Time and Space Complexity

ProgramTimeExtra space
Nested loops (Examples 1–2)O(n²)O(1)
StringBuilder (Example 3)O(n²)O(n) per row buffer

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

Key Takeaways

  • Rule: for each i from 1 to rows, print digits i..rows.
  • Inner start: j = i is what creates the left shift — not spaces.
  • Break the row: call println only after the inner loop.
  • Complexity: O(n²) time; O(1) extra space with direct prints.

One line: for each start i, print i..rows with print, then println().

Frequently Asked Questions

The inner loop starts at j = i, not j = 1. When i increases (1, 2, 3, …), each row begins at that value and prints until rows.
Because each next row starts at a higher i, numbers below i are not printed anymore — the triangle shortens from the left.
System.out.print(j) stays on the same line. System.out.println() ends the current line. Digits use print; the row break uses println after the inner loop.
Program 1 grows by printing 1..i each row. Program 2 starts each row at i and prints i..rows — same total prints, different shape.
Change the rows variable or read it with Scanner. The outer loop runs from 1 to rows, and the inner loop prints j from i to rows.
Yes. Append each digit to a StringBuilder, then println the row — same shape with a different output style. See Example 3.
O(n²) for n rows because total prints are n+(n−1)+…+1 = n(n+1)/2.
Use sc.hasNextInt() before sc.nextInt(), require rows ≥ 1, and reject non-numeric input — see Example 2 notes.

Did you know?

Each row starts at i and prints through rows, so the left edge shifts right each line — still O(n²) total prints for n rows.

Next: Reverse Descending Triangle

Move on to the reverse descending number triangle in the Java number-pattern series.

Program 3 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