C# Hollow Diamond Star Pattern

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

What Is This Pattern?

A hollow diamond star pattern prints only the outline of a diamond: spaces fill the interior, and stars sit on the diagonals. Half-height rows means 2 * rows - 1 printed lines.

Remember
Rule: upper i = 1..rows, then lower i = rows-1..1
      On each row, print "*" where j == i or k == i

    *
   * *
  *   *
 *     *
*       *
 *     *
  *   *
   * *
    *       ← rows = 5 (9 lines)

Build it by stacking Program 7 (upper hollow V) and Program 8 (lower hollow V), starting the second outer loop at rows - 1 so the waist prints once.

How to Solve It

Print one hollow row with two inner loops, then call that idea twice — ascending, then descending past the waist.

MethodIdeaBest for
Dual outer loopsUpper 1..rows, lower rows-1..1, same j/k bodiesLearning, interviews, clearest stack of P7 + P8
Helper + ternaryOne PrintRow(i, rows) called from both halvesLess duplication once the geometry clicks

Pseudocode

Pseudocode
printHollowRow(i, rows):
    for j from rows down to 1:
        print "*" if i == j else " "
    for k from 2 to rows:
        print "*" if i == k else " "
    print newline

for i from 1 to rows:          // upper half
    printHollowRow(i, rows)
for i from rows - 1 down to 1: // lower half (skip waist)
    printHollowRow(i, rows)

Cheat sheet

GoalPattern
Upper halffor (i = 1; i <= rows; i++)
Lower half (no duplicate waist)for (i = rows - 1; i >= 1; i--)
Left diagonalj from rows down to 1; star when i == j
Right diagonalk from 2 to rows; star when i == k
End the rowConsole.WriteLine(); after both inner loops
Filled diamond nextProgram 10

Write vs WriteLine

APIEffectUse for
Console.WriteStays on the same lineEach * or space
Console.WriteLineEnds the current lineAfter both j and k loops

Live Preview

Change the half-height and the hollow diamond updates instantly — including line and outline-star counts.

Whole numbers from 1 to 12. You get 2 * rows - 1 lines. Tap a chip or type a value — the preview redraws as you go.

Live result 5 half · 9 lines · 16 stars
    *    
   * *   
  *   *  
 *     * 
*       *
 *     * 
  *   *  
   * *   
    *    

Worked Walkthrough — rows = 4

Trace each outer value of i. Stars land where j == i (left leg) or k == i (right leg). Spaces show as ·.

HalfiPrinted rowStars
Upper1···*···1
Upper2··*·*··2
Upper3·*···*·2
Upper (waist)4*·····*2
Lower3·*···*·2
Lower2··*·*··2
Lower1···*···1

Lines: 4 + 3 = 7 = 2×4 - 1. Outline stars: 12 = 4×(4 - 1). Width of every line: 7.

C# Programs

Three complete programs: fixed half-height, console input, and a reusable row helper. Use View Output to reveal sample results.

Example 1 — Fixed rows = 5

Upper i = 1..rows, lower i = rows-1..1, same j/k bodies.

C#
using System;

class Program
{
    static void Main()
    {
        int rows = 5;

        // Upper half: i = 1 .. rows
        for (int i = 1; i <= rows; i++)
        {
            for (int j = rows; j >= 1; j--)
            {
                if (i == j)
                    Console.Write("*");
                else
                    Console.Write(" ");
            }
            for (int k = 2; k <= rows; k++)
            {
                if (i == k)
                    Console.Write("*");
                else
                    Console.Write(" ");
            }
            Console.WriteLine();
        }

        // Lower half: skip duplicate waist
        for (int i = rows - 1; i >= 1; i--)
        {
            for (int j = rows; j >= 1; j--)
            {
                if (i == j)
                    Console.Write("*");
                else
                    Console.Write(" ");
            }
            for (int k = 2; k <= rows; k++)
            {
                if (i == k)
                    Console.Write("*");
                else
                    Console.Write(" ");
            }
            Console.WriteLine();
        }
    }
}

How It Works

1. Set half-height. rows = 5 means 5 upper lines and 4 lower lines (9 total).

2. Upper half grows outward. i runs from 1 to rows. Left loop j and right loop k print * only when they equal i.

3. Lower half mirrors without a second waist. i runs from rows - 1 down to 1 with the same inner logic.

4. Break the line. Console.WriteLine() after both inner loops starts the next outline row.

Example 2 — User Input Version

Read the half-height at runtime. Prefer int.TryParse in real apps (shown in the tip below).

C#
using System;

class Program
{
    static void Main()
    {
        Console.Write("Enter the number of rows: ");
        int rows = Convert.ToInt32(Console.ReadLine());

        for (int i = 1; i <= rows; i++)
        {
            for (int j = rows; j >= 1; j--)
                Console.Write(i == j ? "*" : " ");
            for (int k = 2; k <= rows; k++)
                Console.Write(i == k ? "*" : " ");
            Console.WriteLine();
        }

        for (int i = rows - 1; i >= 1; i--)
        {
            for (int j = rows; j >= 1; j--)
                Console.Write(i == j ? "*" : " ");
            for (int k = 2; k <= rows; k++)
                Console.Write(i == k ? "*" : " ");
            Console.WriteLine();
        }
    }
}

How It Works

1. Prompt and read. Ask for a half-height, then convert the line to an int.

2. Same dual-half core. Only the source of rows changes — the print logic matches Example 1 (ternaries shorten the if/else).

3. Safer input tip. Convert.ToInt32 throws on letters or empty input. Prefer:

Safer input
if (!int.TryParse(Console.ReadLine(), out int rows) || rows < 1)
{
    Console.WriteLine("Enter a positive whole number.");
    return;
}

Example 3 — Helper Method

Extract one row printer so the diamond reads as “upper, then lower.”

C#
using System;

class Program
{
    static void PrintRow(int i, int rows)
    {
        for (int j = rows; j >= 1; j--)
            Console.Write(i == j ? "*" : " ");
        for (int k = 2; k <= rows; k++)
            Console.Write(i == k ? "*" : " ");
        Console.WriteLine();
    }

    static void Main()
    {
        int rows = 5;

        for (int i = 1; i <= rows; i++)
            PrintRow(i, rows);

        for (int i = rows - 1; i >= 1; i--)
            PrintRow(i, rows);
    }
}

How It Works

1. One row recipe. PrintRow owns the j/k diagonal logic and the row break.

2. Call it twice. Upper half walks i up; lower half walks i down from rows - 1.

3. Same shape, less copy-paste. Learn the expanded loops first (Example 1), then refactor when the geometry feels familiar.

Edge Cases & Pitfalls

Check these before calling the solution done.

Lower starts at rows

Double waist

If the second outer loop starts at i = rows, the widest line prints twice. Use rows - 1.

k from 1

Extra center column

Right loop must start at k = 2. Starting at 1 overlaps the left half’s last column and skews the diamond.

WriteLine inside

Broken outline

If WriteLine sits inside j or k, the outline collapses into a column. Call it only after both inner loops.

Proportional font

Looks skewed in the IDE

Spaces and stars need a monospace font (console default is fine). Proportional fonts make diagonals look uneven.

rows = 1

Single star

Upper prints one line; lower never runs. Output is just * — a good sanity check.

rows ≤ 0

Empty output

Neither outer loop runs. Validate and re-prompt for interactive programs.

Bad input

Use TryParse

Convert.ToInt32 throws on letters — prefer int.TryParse.

Time and Space Complexity

ProgramTimeExtra space
Dual loops (Examples 1–2)O(rows²)O(1)
Helper method (Example 3)O(rows²)O(1)

Lines printed = 2n - 1. Each line walks about 2n - 1 positions across the two inner loops, so work is still quadratic in n. Outline stars grow as 4(n - 1) for n ≥ 2 (and 1 when n = 1).

Key Takeaways

  • Compose halves: upper 1..rows then lower rows-1..1 — Programs 7 + 8 with one seam fix.
  • Diagonal rule: star only when i == j or i == k; everything else is a space.
  • Break the row: call WriteLine only after both inner loops.
  • Complexity: O(n²) time; O(1) extra space.

One line: print hollow rows for i = 1..rows, then again for i = rows-1..1, starring only the diagonals.

Frequently Asked Questions

Two sequential outer loops share the same inner structure. The first runs i from 1 to rows (upper half). The second runs i from rows minus 1 down to 1 (lower half). On each row, j and k print stars when they equal i.
The first part already prints the widest row when i equals rows. Starting the second part at rows again would duplicate that waist line. rows minus 1 mirrors the upper half without a double middle.
Yes, by mapping a loop index to an effective row i or by branching on upper vs lower half. Splitting into two loops matches Programs 7 and 8 mentally and keeps each block easy to read.
rows + (rows - 1) = 2 * rows - 1 lines. Each line is also 2 * rows - 1 characters wide.
Console.Write stays on the same line. Console.WriteLine ends the current line. Stars and spaces use Write; the row break uses WriteLine after both inner loops.
With n rows, about 2n - 1 printed lines, each with Theta(n) work across two inner loops, giving O(n²).
Program 9 draws only the outline (hollow). Program 10 fills every star in a solid diamond using spaces and 2*i-1 star runs.
Prefer int.TryParse(Console.ReadLine(), out rows) so bad input does not throw FormatException.

Did you know?

This hollow diamond is a direct composition: Program 7’s upper half plus Program 8’s lower half with the duplicate middle row removed by starting the second phase at rows - 1. Total printed lines = 2 * rows - 1.

Next: Filled Diamond

Same half-stacking idea, but with solid centered star runs instead of a hollow outline.

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