Character 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 08 Companion Article
Ten character patterns — alphabet triangles, pyramids, a diamond, a palindrome, boundaries, and mixed-case sequences — each built on Java character arithmetic and row-column thinking instead of memorized output.
Character pattern problems develop control over nested loops, character arithmetic, row-column relationships, spacing, symmetry, and sequence management. Unlike numeric patterns, these problems commonly use char values such as 'A', 'B', and 'Z'.
Java characters internally have numeric Unicode values. Because of this, expressions such as (char) ('A' + i) can generate consecutive uppercase letters.
Important ideas used throughout this chapter:
'A' + 1 produces the numeric value corresponding to B.char when converting numeric character arithmetic back to a character.% 26 can keep generated uppercase letters inside the A-Z range.A
A B
A B C
A B C D
A B C D E
Each row starts from A. For row i, print characters from A through the character at position i. The row number determines how many characters are printed: row 1 → 1 character, row 2 → 2 characters, row 5 → 5 characters.
Use two loops: the outer loop controls rows, the inner loop starts at 0 and runs up to the current row, and the character is calculated using (char) ('A' + j).
public class AlphabetTriangle {
public static void main(String[] args) {
int rows = 5;
for (int i = 0; i < rows; i++) {
for (int j = 0; j <= i; j++) {
char ch = (char) ('A' + j);
System.out.print(ch + " ");
}
System.out.println();
}
}
}
A
A B
A B C
A B C D
A B C D E
For i = 2: j = 0 → A, j = 1 → B, j = 2 → C. Therefore the third row becomes A B C.
The inner-loop variable represents the alphabet offset. When j is 0 → 'A' + 0 → A; 1 → 'A' + 1 → B; 2 → 'A' + 2 → C. Because j <= i, every new row contains one additional character.
O(n²)O(1)j < i instead of j <= i, which prints one fewer character.'A' + j directly, which may print an integer instead of a character.The interviewer may ask you to start each row with a different character instead of always starting from A.
A
A B
A B C
A B C D
A B C D E
An alphabet pyramid combines two responsibilities: printing leading spaces, and printing an increasing alphabet sequence. As the row number increases, spaces decrease while characters increase.
For row i: print rows - i - 1 leading spaces, then print characters from A through the current row position.
public class AlphabetPyramid {
public static void main(String[] args) {
int rows = 5;
for (int i = 0; i < rows; i++) {
for (int space = 0; space < rows - i - 1; space++) {
System.out.print(" ");
}
for (int j = 0; j <= i; j++) {
char ch = (char) ('A' + j);
System.out.print(ch + " ");
}
System.out.println();
}
}
}
A
A B
A B C
A B C D
A B C D E
For rows = 5 and i = 2: leading spaces 5 - 2 - 1 = 2, characters A B C. So the row contains two leading spaces followed by three letters.
The expression rows - i - 1 decreases as i increases. At the same time, j <= i causes the number of characters to increase. These opposite changes produce the pyramid alignment.
O(n²)O(1)When solving any pyramid problem, separate the design into spaces, left-side content, and right-side content if required. This makes complex patterns easier to derive.
A
B B
C C C
D D D D
E E E E E
Every row uses one character repeatedly. The row determines both which alphabet character is selected and how many times it is printed.
For row i: character = 'A' + i. Print that character i + 1 times.
public class RepeatedAlphabetPattern {
public static void main(String[] args) {
int rows = 5;
for (int i = 0; i < rows; i++) {
char ch = (char) ('A' + i);
for (int j = 0; j <= i; j++) {
System.out.print(ch + " ");
}
System.out.println();
}
}
}
A
B B
C C C
D D D D
E E E E E
For i = 3: ch = 'A' + 3 = 'D'. The inner loop executes four times. Result: D D D D.
Unlike an alphabet triangle, the character depends on the outer loop rather than the inner loop. The character is calculated once before the inner loop starts, so it stays unchanged throughout that row.
O(n²)O(1)Calculating the character using j instead of i changes the output into:
A
A B
A B C
That is an alphabet triangle, not a repeated alphabet pattern.
Print:
A A A A A
B B B B
C C C
D D
E
This requires separating character selection from row width.
A
B C
D E F
G H I J
K L M N O
Characters continue across rows instead of restarting at A. A separate character variable must therefore survive between inner-loop iterations and between rows.
Initialize char ch = 'A';. After printing each character, ch++;. Do not reset ch at the beginning of every row.
public class SequentialAlphabetPattern {
public static void main(String[] args) {
int rows = 5;
char ch = 'A';
for (int i = 1; i <= rows; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(ch + " ");
ch++;
}
System.out.println();
}
}
}
A
B C
D E F
G H I J
K L M N O
After row 1, ch becomes B. Row 2 prints B C. After row 2, ch becomes D. Row 3 therefore begins with D.
The character variable exists outside both loops. Its value is retained after each row finishes, creating one continuous sequence.
A direct ch++ eventually goes beyond Z. For repeating A-Z, use an integer counter: char ch = (char) ('A' + count % 26);
public class SequentialAlphabetWrap {
public static void main(String[] args) {
int rows = 8;
int count = 0;
for (int i = 1; i <= rows; i++) {
for (int j = 1; j <= i; j++) {
char ch = (char) ('A' + count % 26);
System.out.print(ch + " ");
count++;
}
System.out.println();
}
}
}
O(n²)O(1)char ch = 'A' inside the outer loop.Z boundary for large patterns.ch once per row instead of once per printed position.This pattern tests variable scope. Be ready to explain why the sequence variable belongs outside the nested loops.
E D C B A
D C B A
C B A
B A
A
Each row starts with a smaller character than the previous row. For five rows: row 1 starts at E, row 2 starts at D, row 3 starts at C.
The starting character for each row can be calculated as 'A' + rows - i - 1. Then decrease the character inside the row.
public class ReverseAlphabetPattern {
public static void main(String[] args) {
int rows = 5;
for (int i = 0; i < rows; i++) {
char ch = (char) ('A' + rows - i - 1);
for (int j = i; j < rows; j++) {
System.out.print(ch + " ");
ch--;
}
System.out.println();
}
}
}
E D C B A
D C B A
C B A
B A
A
For i = 1, the starting character is:
'A' + 5 - 1 - 1
'A' + 3
D
The inner loop executes four times: D C B A.
Increasing i reduces the starting character and the number of positions in the row. The character itself decreases after every print.
O(n²)O(1)ch++ instead of ch--.A simpler reverse triangle may be requested:
E
E D
E D C
E D C B
E D C B A
That variation keeps the starting character fixed and changes only the inner-loop length.
A
A B
A B C
A B C D
A B C
A B
A
A diamond can be treated as two separate patterns:
The center row should appear only once.
Upper half: spaces decrease, characters increase. Lower half: spaces increase, characters decrease.
public class CharacterDiamondPattern {
public static void main(String[] args) {
int rows = 4;
for (int i = 0; i < rows; i++) {
for (int space = 0; space < rows - i - 1; space++) {
System.out.print(" ");
}
for (int j = 0; j <= i; j++) {
char ch = (char) ('A' + j);
System.out.print(ch + " ");
}
System.out.println();
}
for (int i = rows - 2; i >= 0; i--) {
for (int space = 0; space < rows - i - 1; space++) {
System.out.print(" ");
}
for (int j = 0; j <= i; j++) {
char ch = (char) ('A' + j);
System.out.print(ch + " ");
}
System.out.println();
}
}
}
A
A B
A B C
A B C D
A B C
A B
A
The upper half already prints the widest row. If the lower half started from rows - 1, the center row would appear twice. Using rows - 2 removes that duplication.
O(n²)O(1)For symmetric patterns, first solve the upper and lower halves separately. Combine them only after both parts work correctly.
A
A B A
A B C B A
A B C D C B A
Each row has two alphabet sequences: an increasing sequence and a decreasing sequence. The highest character should not be repeated in the descending half.
For row i: ascending goes from A to the current character, and descending goes from the previous character back to A. For example, when i = 2: ascending is A B C, descending is B A, combined as A B C B A.
public class PalindromicAlphabetPattern {
public static void main(String[] args) {
int rows = 4;
for (int i = 0; i < rows; i++) {
for (int space = 0; space < rows - i - 1; space++) {
System.out.print(" ");
}
for (int j = 0; j <= i; j++) {
char ch = (char) ('A' + j);
System.out.print(ch + " ");
}
for (int j = i - 1; j >= 0; j--) {
char ch = (char) ('A' + j);
System.out.print(ch + " ");
}
System.out.println();
}
}
}
A
A B A
A B C B A
A B C D C B A
For i = 3: the first loop prints A B C D, the second loop starts from 2 and prints C B A. Final row: A B C D C B A.
The peak character is produced by the first loop. The second loop begins from i - 1 rather than i. This prevents the center character from being printed twice and creates the palindrome.
O(n²)O(1)i, producing A B C C B A.Print a centered palindrome where every row starts from its row character:
A
B A B
C B A B C
This requires a different relationship between row and character offset.
A B C D E
A B C D E
A B C D E
A B C D E
A B C D E
A square pattern has a fixed number of rows and columns. The row does not influence the character sequence. Only the column controls the printed character.
For every row: start from column 0, convert the column number into a character, and print exactly size characters.
public class CharacterSquarePattern {
public static void main(String[] args) {
int size = 5;
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
char ch = (char) ('A' + col);
System.out.print(ch + " ");
}
System.out.println();
}
}
}
A B C D E
A B C D E
A B C D E
A B C D E
A B C D E
The character uses 'A' + col. The value of row is not used in character calculation, so every row contains the same sequence.
Another common pattern is:
A A A A A
B B B B B
C C C C C
D D D D D
E E E E E
For that version, use char ch = (char) ('A' + row);
O(n²)O(1)Before coding a matrix-style pattern, determine whether each cell depends on row, column, row + column, or row - column. That usually reveals the required formula.
For size = 5:
A B C D E
A E
A E
A E
A B C D E
Only characters on the boundary are printed. A position belongs to the boundary when it is in the first row, last row, first column, or last column. All internal cells contain spaces.
row == 0
row == size - 1
col == 0
col == size - 1
These conditions can be joined using logical OR.
public class CharacterBoundaryPattern {
public static void main(String[] args) {
int size = 5;
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
if (row == 0 || row == size - 1 || col == 0 || col == size - 1) {
char ch = (char) ('A' + col);
System.out.print(ch + " ");
} else {
System.out.print(" ");
}
}
System.out.println();
}
}
}
A B C D E
A E
A E
A E
A B C D E
Consider:
row = 2
col = 2
Checks: row == 0 → false, row == 4 → false, col == 0 → false, col == 4 → false. Therefore the position is internal, so spaces are printed. Now consider:
row = 2
col = 4
The condition col == size - 1 is true, so E is printed.
Every boundary cell satisfies at least one of the four edge conditions. Internal cells satisfy none of them. This same technique is useful for hollow squares, rectangles, matrices, frames, and border patterns.
O(n²)O(1)"X ", causing alignment problems.size - 1 last-index rule.For size = 1, the only cell is simultaneously the first and last row and column, so it is correctly printed.
Boundary conditions are more important than character arithmetic in this problem. Explain the row-column condition clearly before discussing the letter calculation.
Mixed character patterns combine multiple rules rather than following one simple alphabet sequence. A common example alternates letters based on position.
A
B C
D E F
G H I J
K L M N O
A more useful mixed variation combines uppercase and lowercase characters:
A
a B
C d E
f G h I
J k L m N
The printed character depends on a condition in addition to the sequence. For example: even sequence position → uppercase, odd sequence position → lowercase. This tests both pattern traversal and conditional logic.
public class MixedCharacterPattern {
public static void main(String[] args) {
int rows = 5;
int count = 0;
for (int i = 1; i <= rows; i++) {
for (int j = 1; j <= i; j++) {
char upper = (char) ('A' + count % 26);
if (count % 2 == 0) {
System.out.print(upper + " ");
} else {
char lower = Character.toLowerCase(upper);
System.out.print(lower + " ");
}
count++;
}
System.out.println();
}
}
}
A
b C
d E f
G h I j
K l M n O
Initial value: count = 0. Position 1:
upper = A
0 % 2 == 0
output = A
Position 2:
count = 1
upper = B
odd position
output = b
Position 3:
count = 2
upper = C
even position
output = C
The sequence therefore alternates uppercase and lowercase letters continuously.
count performs two jobs: it determines the next alphabet character, and it determines uppercase or lowercase formatting. The expression count % 26 also prevents the alphabet offset from increasing indefinitely beyond Z.
O(n²)O(1)count for every row.Character.toLowerCase() is clearer.Mixed character patterns may combine uppercase and lowercase letters, letters and numbers, alternating characters, vowels and consonants, row-based and column-based characters, or alphabet sequences with symbols. The first task is always to identify which property controls each printed position.
Character patterns become easier once Java character arithmetic is understood.
char ch = (char) ('A' + index);
| index | Character |
|---|---|
| 0 | A |
| 1 | B |
| 2 | C |
| 3 | D |
| 25 | Z |
The cast is required because arithmetic involving char values produces an int.
Use char ch = (char) ('a' + index); For example, char ch = (char) ('a' + 2); results in c.
For continuously increasing sequences: char ch = (char) ('A' + count % 26); When count reaches 26, 26 % 26 = 0 and the sequence begins again from A. This produces ... X Y Z A B C ...
Java provides built-in character conversion methods.
char upper = Character.toUpperCase(ch);
char lower = Character.toLowerCase(ch);
These are preferable to manually adding or subtracting fixed ASCII differences.
Most character patterns can be solved by examining the relationship between row and column. For example:
char ch = (char) ('A' + col); Produces rows such as A B C D.
char ch = (char) ('A' + row); Produces:
A A A A
B B B B
C C C C
char ch = (char) ('A' + row + col); Produces diagonal alphabet progression. Example:
A B C
B C D
C D E
This relationship is frequently used in interview pattern questions.
A B C D
B C D E
C D E F
D E F G
public class RowColumnCharacterPattern {
public static void main(String[] args) {
int size = 4;
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
char ch = (char) ('A' + row + col);
System.out.print(ch + " ");
}
System.out.println();
}
}
}
A B C D
B C D E
C D E F
D E F G
At (row, col): offset = row + col.
| Row | Column | Offset | Character |
|---|---|---|---|
| 0 | 0 | 0 | A |
| 0 | 2 | 2 | C |
| 1 | 0 | 1 | B |
| 2 | 2 | 4 | E |
This demonstrates why deriving a mathematical relationship is often better than manually updating character variables.
When you receive an unfamiliar character pattern, avoid writing nested loops immediately. Follow this sequence.
Determine the number of output lines. The outer loop normally represents these rows.
Check whether the number of printed values stays fixed, increases, or decreases. This determines the main inner-loop boundary.
For centered patterns, calculate how spaces change between rows. Common formula: rows - i - 1.
Check whether the character depends on the current row, current column, row + column, a global counter, or the previous character.
Determine whether letters increase from A, decrease toward A, restart each row, or continue between rows.
For patterns such as A B C B A, separate the sequence into an increasing part and a decreasing part.
If the input can produce more than 26 characters, decide whether the expected behavior should continue into other Unicode characters, wrap from Z to A, or reject oversized input. For alphabet-only interview problems, wrapping or validating input is usually safer.
Incorrect idea: System.out.print('A' + j); Character arithmetic may produce a numeric value. Use: System.out.print((char) ('A' + j));
For a row that must contain i + 1 values, j <= i is different from j < i. A one-character difference can change the entire pattern.
For continuously sequential patterns, this is usually wrong:
for (...) {
char ch = 'A';
}
It restarts the alphabet every row. Declare the character or counter outside the outer loop when the sequence must continue.
For pyramids and diamonds, correct character generation alone is not enough. Spacing is part of the pattern logic. Always derive these separately:
number of spaces
number of characters
For A B C B A, the reverse loop must begin from B, not C. If the peak index is i, reverse from i - 1.
If the upper half reaches row n - 1, the lower half should usually begin from n - 2. Otherwise the widest row appears twice.
Most basic character patterns use nested loops. For n rows, the total number of operations is generally proportional to 1 + 2 + 3 + ... + n, which is approximately n² / 2. Therefore the time complexity is normally O(n²).
Additional variables such as i, j, ch, and count require constant memory. Space complexity is usually O(1). The printed output itself is normally not counted as auxiliary space.
Use char when working with a single character: char ch = 'A'; Use String when working with multiple characters: String text = "ABC"; Pattern problems based on individual alphabet values are usually cleaner with char.
Java uses Unicode characters. Basic English uppercase letters still appear in consecutive order, so calculations such as 'A' + 1 work correctly for A-Z. However, character pattern logic should not be described as depending exclusively on ASCII because Java's char type represents UTF-16 code units.
If a program specifically supports only uppercase English alphabet patterns, very large row values may move beyond Z. A simple validation can restrict rows:
if (rows < 1 || rows > 26) {
System.out.println("Rows must be between 1 and 26.");
return;
}
Use this when wrapping back to A is not part of the problem requirement.
| Pattern | Main Logic |
|---|---|
| Alphabet Triangle | Character depends on column |
| Alphabet Pyramid | Spaces decrease, letters increase |
| Repeated Alphabet | Character depends on row |
| Sequential Alphabet | Global character counter |
| Reverse Alphabet | Character decreases |
| Character Diamond | Increasing + decreasing halves |
| Palindromic Alphabet | Forward + reverse sequence |
| Character Square | Fixed rows and columns |
| Character Boundary | Print only edge positions |
| Mixed Character | Character rule plus conditions |
Character pattern questions are useful because they test several fundamental programming skills at the same time.
You must know which loop controls rows, columns, spaces, and characters.
A variable declared outside both loops can preserve state across rows; inside the outer loop it resets once per row; inside the inner loop it resets once per printed position. Sequential alphabet patterns are particularly useful for testing this concept.
You should be comfortable with (char) ('A' + index) and understand why the cast is required.
Hollow and boundary patterns test expressions such as row == 0 || row == n - 1 || col == 0 || col == n - 1.
Diamond and palindrome patterns test whether a complex shape can be decomposed into simpler sections.
Strong pattern solutions usually derive values from row and column positions rather than relying on many manually updated variables.
After understanding the basic patterns, try solving these without copying the original programs.
A
B C
D E F
G H I J
Use one continuous character counter.
A
B B
C C C
D D D D
Character depends on row.
D C B A
C B A
B A
A
Both row length and starting character decrease.
A B C D
B C D E
C D E F
D E F G
Character depends on row + column.
A B C D
A D
A D
A B C D
Use boundary conditions.
A
A B A
A B C B A
A B C D C B A
Use increasing and decreasing character sequences.
A
b C
d E f
G h I j
Maintain a global position counter and apply case conversion based on parity.
(char) ('A' + index) for alphabet generation.'a' instead of 'A' for lowercase patterns.% 26 when an alphabet sequence must wrap after Z.A-Z.O(n²) time complexity and O(1) auxiliary space.