Number Pattern Problems
Solve one Java logic problem at a time, then flip for the complete explanation and program.
Solve one Java logic problem at a time, then flip for the complete explanation and program.
Java Logic Development · Chapter 07 Companion Article
Fourteen number patterns — counters, triangles, Pascal's and palindromic pyramids, binary grids, a diamond, concentric layers, a snake, and a spiral — each solved by connecting row, column, and value instead of memorizing output.
Number pattern problems are useful for developing control over nested loops, row-column relationships, counters, arithmetic conditions, matrix traversal, and mathematical logic.
Most number patterns can be solved by answering three questions:
The outer loop normally controls rows. The inner loop controls columns or values printed inside each row.
Print numbers continuously from left to right across multiple rows. For n = 4:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
A separate counter is required because the printed number depends on the total number of values already printed, not directly on the current row or column. Start number from 1 and increment it after every print operation.
public class SequentialNumberPattern {
public static void main(String[] args) {
int n = 4;
int number = 1;
for (int row = 1; row <= n; row++) {
for (int col = 1; col <= n; col++) {
System.out.print(number + " ");
number++;
}
System.out.println();
}
}
}
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
The nested loops generate n × n positions. The number variable advances independently after each position, producing one continuous sequence.
O(n²)O(1)Resetting number inside the outer loop causes every row to restart from 1.
A sequential value does not always require a separate counter. The value at (row, col) can also be calculated using (row - 1) * n + col.
Print the current row number repeatedly in that row. For n = 5:
1
2 2
3 3 3
4 4 4 4
5 5 5 5 5
The row number itself is the value to print. Row r contains exactly r values.
public class RepeatedNumberPattern {
public static void main(String[] args) {
int n = 5;
for (int row = 1; row <= n; row++) {
for (int col = 1; col <= row; col++) {
System.out.print(row + " ");
}
System.out.println();
}
}
}
1
2 2
3 3 3
4 4 4 4
5 5 5 5 5
The inner loop executes row times. Because row is printed on each iteration, the number and repetition count increase together.
O(n²)O(1)The actual number of print operations is 1 + 2 + 3 + ... + n, which equals n(n + 1) / 2.
Print numbers from 1 up to the current row number. For n = 5:
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
The column position determines the value. For every row, printed value = col.
public class IncreasingNumberTriangle {
public static void main(String[] args) {
int n = 5;
for (int row = 1; row <= n; row++) {
for (int col = 1; col <= row; col++) {
System.out.print(col + " ");
}
System.out.println();
}
}
}
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
Each row contains as many columns as its row number. Since col starts from 1, every row naturally produces 1 through row.
O(n²)O(1)Printing row instead of col changes the pattern into a repeated-number triangle.
Start with n values and reduce the number of printed values after every row. For n = 5:
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1
For row r, the number of columns is n - row + 1. The column number itself is printed.
public class DecreasingNumberTriangle {
public static void main(String[] args) {
int n = 5;
for (int row = 1; row <= n; row++) {
for (int col = 1; col <= n - row + 1; col++) {
System.out.print(col + " ");
}
System.out.println();
}
}
}
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1
As row increases, n - row + 1 decreases. Therefore, every new row contains one fewer value.
O(n²)O(1)Print numbers in descending order within every row. For n = 5:
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
The inner loop begins from the current row number and moves backward to 1.
public class ReverseNumberTriangle {
public static void main(String[] args) {
int n = 5;
for (int row = 1; row <= n; row++) {
for (int number = row; number >= 1; number--) {
System.out.print(number + " ");
}
System.out.println();
}
}
}
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
Row r starts from r, and the inner variable decreases until it reaches 1.
O(n²)O(1)You may be asked to print:
5 4 3 2 1
4 3 2 1
3 2 1
2 1
1
That variation requires changing both the starting value and row length.
Print consecutive natural numbers in triangular form. For n = 5:
1
2 3
4 5 6
7 8 9 10
11 12 13 14 15
Maintain one counter across all rows. Row r contains r numbers.
public class FloydTriangle {
public static void main(String[] args) {
int n = 5;
int number = 1;
for (int row = 1; row <= n; row++) {
for (int col = 1; col <= row; col++) {
System.out.print(number + " ");
number++;
}
System.out.println();
}
}
}
1
2 3
4 5 6
7 8 9 10
11 12 13 14 15
For n = 3:
122 344 5 6O(n²)O(1)The final number printed after n rows is n(n + 1) / 2.
Print Pascal's Triangle. For n = 5:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
Each interior number is the sum of the two values above it. Pascal's Triangle is also based on binomial coefficients: C(row, col). Instead of repeatedly calculating factorials, the next value in a row can be derived from the previous value.
If the current value is value, the next one is value = value * (row - col) / col when rows are treated using zero-based mathematical indexing.
public class PascalTriangle {
public static void main(String[] args) {
int n = 5;
for (int row = 0; row < n; row++) {
int value = 1;
for (int col = 0; col <= row; col++) {
System.out.print(value + " ");
value = value * (row - col) / (col + 1);
}
System.out.println();
}
}
}
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
The first value of every row is always 1. Every later value is calculated from the previous binomial coefficient. This avoids separate factorial calculations.
O(n²)O(1)For large row numbers, int can overflow. Use long or BigInteger when larger coefficients are required.
Generating Pascal's Triangle through factorial calculations is valid but unnecessarily expensive and more vulnerable to overflow.
Create a centered pyramid whose rows read the same forward and backward. For n = 5:
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
Each row has three parts:
row to 12 to rowpublic class PalindromicNumberPyramid {
public static void main(String[] args) {
int n = 5;
for (int row = 1; row <= n; row++) {
for (int space = 1; space <= n - row; space++) {
System.out.print(" ");
}
for (int number = row; number >= 1; number--) {
System.out.print(number + " ");
}
for (int number = 2; number <= row; number++) {
System.out.print(number + " ");
}
System.out.println();
}
}
}
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
The value 1 forms the center of every row. The decreasing sequence creates the left half, while the increasing sequence mirrors it on the right.
O(n²)O(1)Starting the second number loop from 1 prints the center value twice.
Print alternating 0 and 1 values across rows and columns. For n = 5:
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
The value depends on whether row + col is even or odd. Using zero-based indexes: value = (row + col) % 2.
public class BinaryNumberPattern {
public static void main(String[] args) {
int n = 5;
for (int row = 0; row < n; row++) {
for (int col = 0; col < n; col++) {
System.out.print((row + col) % 2 + " ");
}
System.out.println();
}
}
}
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
Moving one position horizontally or vertically changes the parity of row + col, so the value alternates automatically.
O(n²)O(1)Parity expressions such as (row + col) % 2 are often more useful than manually switching a boolean or integer variable.
Print a triangular alternating binary pattern. For n = 5:
1
0 1
1 0 1
0 1 0 1
1 0 1 0 1
Using one-based row and column numbers, (row + col) % 2 == 0 prints 1; otherwise it prints 0.
public class ZeroOneTriangle {
public static void main(String[] args) {
int n = 5;
for (int row = 1; row <= n; row++) {
for (int col = 1; col <= row; col++) {
int value = (row + col) % 2 == 0 ? 1 : 0;
System.out.print(value + " ");
}
System.out.println();
}
}
}
1
0 1
1 0 1
0 1 0 1
1 0 1 0 1
Positions with an even row + col receive 1, while positions with an odd sum receive 0.
O(n²)O(1)The binary square contains exactly n columns in every row. The 0-1 triangle contains only row columns.
Create a diamond using repeated row numbers. For n = 4:
1
2 2 2
3 3 3 3 3
4 4 4 4 4 4 4
3 3 3 3 3
2 2 2
1
For row r in the upper half, values = 2 * r - 1. The lower half performs the same logic in reverse.
public class NumberDiamondPattern {
public static void main(String[] args) {
int n = 4;
for (int row = 1; row <= n; row++) {
for (int space = 1; space <= n - row; space++) {
System.out.print(" ");
}
for (int col = 1; col <= 2 * row - 1; col++) {
System.out.print(row + " ");
}
System.out.println();
}
for (int row = n - 1; row >= 1; row--) {
for (int space = 1; space <= n - row; space++) {
System.out.print(" ");
}
for (int col = 1; col <= 2 * row - 1; col++) {
System.out.print(row + " ");
}
System.out.println();
}
}
}
1
2 2 2
3 3 3 3 3
4 4 4 4 4 4 4
3 3 3 3 3
2 2 2
1
The upper half increases the number of elements by two per row. The lower half reverses the process.
O(n²)O(1)Starting the lower half from n prints the widest row twice.
Print numbers in nested rectangular layers. For n = 4:
4 4 4 4 4 4 4
4 3 3 3 3 3 4
4 3 2 2 2 3 4
4 3 2 1 2 3 4
4 3 2 2 2 3 4
4 3 3 3 3 3 4
4 4 4 4 4 4 4
For input n, the matrix dimension is 2 * n - 1. For n = 4, size = 7.
The value depends on the cell's minimum distance from any edge. For coordinates (row, col), calculate:
top = row
left = col
bottom = size - 1 - row
right = size - 1 - col
The minimum of these distances identifies the current layer. Then value = n - minimumDistance.
public class ConcentricNumberPattern {
public static void main(String[] args) {
int n = 4;
int size = 2 * n - 1;
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
int top = row;
int left = col;
int bottom = size - 1 - row;
int right = size - 1 - col;
int distance = Math.min(Math.min(top, bottom), Math.min(left, right));
System.out.print((n - distance) + " ");
}
System.out.println();
}
}
}
4 4 4 4 4 4 4
4 3 3 3 3 3 4
4 3 2 2 2 3 4
4 3 2 1 2 3 4
4 3 2 2 2 3 4
4 3 3 3 3 3 4
4 4 4 4 4 4 4
All cells equally distant from the nearest border belong to the same layer. The outer layer has distance 0, the next layer distance 1, and so on.
Since the matrix size is approximately 2n × 2n:
O(n²)O(1)This pattern is more useful than simple triangle patterns because it tests matrix-coordinate reasoning instead of only nested-loop repetition.
Print sequential numbers from left to right on one row and right to left on the next. For n = 4:
1 2 3 4
8 7 6 5
9 10 11 12
16 15 14 13
Odd-numbered rows move left to right. Even-numbered rows represent the same sequence in reverse. Instead of creating an array, calculate the value directly. For odd rows: value = (row - 1) * n + col. For even rows: value = row * n - col + 1.
public class SnakeNumberPattern {
public static void main(String[] args) {
int n = 4;
for (int row = 1; row <= n; row++) {
for (int col = 1; col <= n; col++) {
int value;
if (row % 2 != 0) {
value = (row - 1) * n + col;
} else {
value = row * n - col + 1;
}
System.out.print(value + " ");
}
System.out.println();
}
}
}
1 2 3 4
8 7 6 5
9 10 11 12
16 15 14 13
For row 2, n = 4. At column 1:
value = 2 * 4 - 1 + 1
value = 8
At column 4:
value = 2 * 4 - 4 + 1
value = 5
So row 2 becomes 8 7 6 5.
O(n²)O(1)A snake pattern is closely related to zigzag matrix traversal. The same technique appears when traversing two-dimensional arrays.
Fill a matrix with sequential numbers in clockwise spiral order. For n = 4:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
Simple patterns usually print values immediately. A spiral pattern is easier to solve by first filling a two-dimensional array because movement changes direction repeatedly. Four boundaries are maintained: top, bottom, left, and right.
Each cycle performs:
After each traversal, the corresponding boundary moves inward.
public class SpiralNumberPattern {
public static void main(String[] args) {
int n = 4;
int[][] matrix = new int[n][n];
int top = 0;
int bottom = n - 1;
int left = 0;
int right = n - 1;
int number = 1;
while (top <= bottom && left <= right) {
for (int col = left; col <= right; col++) {
matrix[top][col] = number++;
}
top++;
for (int row = top; row <= bottom; row++) {
matrix[row][right] = number++;
}
right--;
if (top <= bottom) {
for (int col = right; col >= left; col--) {
matrix[bottom][col] = number++;
}
bottom--;
}
if (left <= right) {
for (int row = bottom; row >= top; row--) {
matrix[row][left] = number++;
}
left++;
}
}
for (int row = 0; row < n; row++) {
for (int col = 0; col < n; col++) {
System.out.print(matrix[row][col] + " ");
}
System.out.println();
}
}
}
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
Initially:
top = 0
bottom = 3
left = 0
right = 3
First traversal fills 1 2 3 4. Then the right edge receives:
5
6
7
The bottom edge is filled backward: 10 9 8 7. The left edge is filled upward:
12
11
10
The boundaries then move inward and the same process fills:
13 14
16 15
After reducing top, bottom, left, or right, some boundaries can cross. Without checks such as if (top <= bottom), a row or column may be processed twice for certain matrix sizes.
O(n²)O(n²)O(n²)O(n²)Spiral traversal is an important matrix problem. Interviewers may ask variations such as:
| Pattern | Main Logic Concept | Extra Storage |
|---|---|---|
| Sequential Number | Global counter | O(1) |
| Repeated Number | Row-controlled value | O(1) |
| Increasing Triangle | Column-controlled value | O(1) |
| Decreasing Triangle | Decreasing row width | O(1) |
| Reverse Triangle | Reverse inner loop | O(1) |
| Floyd's Triangle | Continuous counter | O(1) |
| Pascal's Triangle | Binomial coefficient | O(1) |
| Palindromic Pyramid | Mirror sequence | O(1) |
| Binary Pattern | Row-column parity | O(1) |
| 0-1 Triangle | Position parity | O(1) |
| Number Diamond | Upper/lower symmetry | O(1) |
| Concentric Pattern | Distance from boundary | O(1) |
| Snake Pattern | Row parity | O(1) |
| Spiral Pattern | Matrix boundaries | O(n²) |
First determine whether the pattern has:
For example:
1
1 2
1 2 3
has increasing width, so the inner-loop condition naturally becomes col <= row.
Check whether the printed value depends on:
rowcolrow + colExamples: repeated pattern uses value = row, increasing triangle uses value = col, binary pattern uses value = (row + col) % 2.
Pattern problems normally contain two independent decisions. Shape logic: should something be printed at this position? Value logic: what should be printed? This distinction becomes particularly useful for pyramids, diamonds, hollow patterns, and matrices.
A counter is useful when values must continue across rows:
1
2 3
4 5 6
But a counter is unnecessary when the value can be calculated directly from row and column positions. For example, in an n × n sequential matrix, value = row * n + col + 1 when using zero-based indexes.
Patterns such as diamonds and palindromic pyramids are usually easier when divided into independent halves. For a diamond:
Usually controls the number of rows. Example: for (int row = 1; row <= n; row++).
Usually controls numbers, columns, spaces, or repeated values. Example: for (int col = 1; col <= row; col++).
Complex patterns may require separate loops for leading spaces, left-side values, and right-side values. For example, a palindromic pyramid uses all three.
For an n × n matrix with one-based indexes:
| Formula | Expression |
|---|---|
| Sequential value | (row - 1) * n + col |
| Snake odd row | (row - 1) * n + col |
| Snake even row | row * n - col + 1 |
| Binary alternating position | (row + col) % 2 |
| Triangle values in row r | r |
| Diamond width at row r | 2 * r - 1 |
| Concentric matrix size | 2 * n - 1 |
These formulas are more important than memorizing complete programs.
Using col <= n instead of col <= row changes a triangle into a rectangle.
For Floyd's Triangle, this is incorrect:
for (int row = 1; row <= n; row++) {
int number = 1;
// ...
}
The counter would restart for each row. Declare it before the outer loop.
In a palindromic pattern, 3 2 1 1 2 3 is not the intended palindrome when the desired center is one 1. Start the second loop from 2, not 1.
If the top half ends at n, the bottom half should normally begin at n - 1.
Expressions such as (row + col) % 2 can produce a reversed binary pattern depending on whether the loops begin from 0 or 1. Use one indexing convention consistently.
Pascal's Triangle values increase rapidly. Using int is suitable only for relatively small rows. Larger calculations may require long or BigInteger.
Most patterns in this chapter should be generated directly using loop variables and formulas. Examples include:
Direct generation usually provides:
O(1) auxiliary spaceSpiral filling is an exception when the final matrix itself must be displayed after values are placed according to changing traversal directions.
Nested loops do not automatically mean exactly n² operations. For a triangle, 1 + 2 + 3 + ... + n operations occur. This is n(n + 1) / 2. Asymptotically, this is O(n²).
For a square, n * n operations occur, which is also O(n²). Although both have the same Big-O complexity, their actual number of operations differs.
After understanding the basic patterns, practice changing one constraint at a time. Useful variations include:
n01These variations test whether you understand the underlying row-column relationship rather than memorizing output.
Simple patterns prepare you for matrix-based problems because both rely on coordinates. A matrix position is normally represented as matrix[row][col]. The value at that position may depend on:
Concentric and spiral patterns are especially useful for developing this type of reasoning.
Recognizing the pattern category usually makes the implementation much simpler.
Before considering number patterns complete, you should be able to write these without copying code:
More importantly, you should be able to explain why each inner-loop boundary and printed-value formula is correct.