Hollow Diamond Star Pattern in C#

Beginner
⏱️ 11 min read
📚 Updated: Aug 2026
🎯 3 Code Examples
🚀 Live Preview
2n − 1 rows

What You’ll Learn

A hollow diamond stacks an inverted V (Program 7) on top of a V (Program 8 style), sharing the same if (i == j) / if (i == k) legs and skipping a duplicate middle row by starting the lower half at rows - 1. This tutorial covers both halves, a live preview, algorithm steps, worked C# examples, edge cases, and complexity.

Shape Rule

Outline only

Apex, widening waist, then narrowing tip — stars on edges only.

Upper Half

i = 1..rows

Program 7’s inverted hollow V grows to the waist.

Lower Half

i = rows-1..1

Program 8’s V mirrors down without reprinting the waist.

Same Legs

j + k

Identical inner loops on both halves — star when indices match.

Live Preview

1–12 rows

Pick a height and draw the hollow diamond instantly.

O(n²)

2n - 1 lines

About 2n−1 rows × Θ(n) cells → O(n²) time, O(1) extra space.

Introduction

A hollow diamond is two familiar outlines stacked: widen with an inverted V, then narrow with a V — stars only on the diagonals.

If you already know Program 7 and Program 8, this page is mostly composition: run the first half fully, then the second from rows - 1. For a solid fill, see Program 10.

Why it matters?

Composition beats reinventing formulas. Once halves click, diamonds (hollow or filled) become “stack and skip the duplicate waist” — a reusable design habit.

Key Highlights

Two Halves

Upper Program 7 + lower Program 8.

Skip Duplicate

Lower starts at rows - 1.

Shared Legs

Same j/k equality tests.

Fixed Width

Every line is 2n - 1 characters.

In short: print Program 7 for i = 1..rows, then the same row body for i = rows-1..1 — one waist, full hollow diamond.

📝 Problem & Approach

Given a positive integer rows, print a hollow diamond outline of * characters with 2 * rows - 1 lines, each of width 2 * rows - 1.

C#
// rows = 5 (spaces shown as ·) — 9 lines, width 9
// ····*····
// ···*·*···
// ··*···*··
// ·*·····*·
// *·······*
// ·*·····*·
// ··*···*··
// ···*·*···
// ····*····

Inputs & Outputs

ItemTypeDescription
rowsintHalf-height to the waist (typically ≥ 1). Total lines = 2 * rows - 1.
Printed outputtextHollow diamond outline; interior spaces only.

Minimal workflow

Pseudocode
for i from 1 to rows:          // upper half
    print_row(i, rows)
for i from rows - 1 down to 1: // lower half
    print_row(i, rows)

print_row(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

Approach comparison

ApproachIdeaBest for
Two outer loopsProgram 7 then Program 8 from rows-1Learning and interviews
Helper + ternariesOne PrintRow method reused twiceCleaner demos after halves click

⚡ Quick Reference

GoalPattern
Upper halffor (i = 1; i <= rows; i++)
Lower halffor (i = rows - 1; i >= 1; i--)
Left / right legsj = rows..1 + k = 2..rows with i == j / i == k
Line count & width2 * rows - 1
Avoid double waistNever start lower half at i == rows
Filled variantSee Program 10

📋 Hollow Diamond vs Halves vs Filled

Same legs — stacking and fill rules define the family.

Program 7
upper only

Inverted hollow V

Program 8
lower only

Upright hollow V

This page
7 + 8

Hollow diamond outline

Program 10
solid fill

Filled diamond — spaces + odd stars

Context

When This Pattern Shows Up

Reach for a hollow diamond when teaching composition after the V halves are solid.

  1. After Programs 7 & 8

    Capstone for the hollow-outline mini-series.

  2. Composition labs

    “Reuse, don’t rewrite” — stack known blocks.

  3. Before filled diamonds

    Outline first; then switch to solid star runs in Program 10.

  4. Off-by-one practice

    Starting lower at rows vs rows - 1 is a classic bug.

  5. Not a UI layout tool

    Console teaching pattern — not how you build app screens.

Key benefit: proves complex shapes are often stacked simpler ones — with one careful off-by-one at the seam.

🔮 Live Preview

Choose a height between 1 and 12 and draw the hollow diamond in the browser.

Try 4, 5, or 7. You will get 2 * rows - 1 lines.

Live result
Press "Draw diamond".

Examples Gallery

Three complete C# programs — classic dual outer loops, console input, and a reusable row helper with ternaries. Click View Output to reveal sample console results.

📚 Getting Started

Print a five-row-half hollow diamond with two outer loops.

Example 1 — Fixed rows = 5

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

C#
using System;

namespace MyApp
{
    class Program
    {
        static void Main(string[] args)
        {
            int i, j, k;
            int rows = 5;

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

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

How It Works

The first loop prints 5 lines (apex to waist). The second prints 4 more (waist−1 to tip) — 9 lines total, waist printed once.

📈 Practical Variant

Let the user choose the half-height at runtime.

Example 2 — User Input Version

Read rows with Console.ReadLine() (prefer int.TryParse in real apps).

C#
using System;

namespace MyApp
{
    class Program
    {
        static void Main(string[] args)
        {
            int rows;
            int i, j, k;

            Console.Write("Enter the number of rows: ");
            rows = Convert.ToInt32(Console.ReadLine());

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

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

How It Works

Same dual-half core as Example 1; only the source of rows changes. Non-numeric input throws with Convert.ToInt32 — switch to TryParse for safer labs.

⚡ Shortcut Style

Extract one row printer and call it from both halves.

Example 3 — Helper Method + Ternary

Reuse PrintRow so the diamond is clearly “upper then lower.”

C#
using System;

namespace MyApp
{
    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(string[] args)
        {
            int rows = 5;
            int i;

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

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

How It Works

Same geometry as Example 1; duplication of the leg loops is gone. Great when you already understand Programs 7 and 8 and want the composition to read clearly.

🧠 How the Algorithm Prints Rows

1

Upper half

for (i = 1; i <= rows; i++) — Program 7: apex to waist.

Expanding
2

Lower half

for (i = rows - 1; i >= 1; i--) — Program 8 style: skip duplicate waist.

Mirrored
3

Shared legs

Left j = rows..1 and right k = 2..rows with i == j / i == k on every row.

Diagonals
4

Width & line count

Each line is 2 * rows - 1 chars; total lines = 2 * rows - 1.

Layout
=

Full hollow diamond

O(n²) time for n = rows, O(1) extra space. Waist printed once.

🔎 Worked Walkthrough — rows = 4

Seven printed lines: upper i = 1..4, then lower i = 3..1 (width = 7).

PhaseiStarsPrinted row
Upper11 (apex)   *   
Upper22  * *  
Upper32 *   * 
Upper42 (waist)*     *
Lower32 *   * 
Lower22  * *  
Lower11 (tip)   *   

If the lower loop started at i = 4, the waist would appear twice — that is the key off-by-one.

Use Cases

Where this hollow diamond (and half-stacking) shows up beyond the homework prompt.

1. Teaching Composition

Build complex shapes from known halves.

Example: assign Program 7 then “add the mirror.”

2. Contrast With Filled Diamond

Outline vs solid star runs side by side.

Example: Program 10.

3. Extract a PrintRow Helper

DRY the duplicated leg loops once halves click.

Example: Example 3 above.

4. Off-by-One Drills

Start lower at rows on purpose, then fix to rows - 1.

Example: spot the double waist visually.

5. Symbol Variants

Swap * for # or digits at match positions.

Example: print i on the diagonals.

6. Input Validation Labs

Pair with TryParse and positive-row checks.

Example: reject rows <= 0 and re-prompt.

Pro Tip: say “Program 7, then Program 8 from rows - 1” before writing a single loop — that is the whole design.

Advantages

Why the hollow diamond is a favorite series capstone.

  1. 1. Builds on Known Halves

    No new diagonal formulas — only stacking.

  2. 2. Instant Seam Feedback

    A double waist is obvious when the lower loop is wrong.

  3. 3. Gateway to Filled Diamonds

    Same half idea; Program 10 changes how cells fill.

  4. 4. Easy to Refactor

    Extract PrintRow once the structure is clear.

Pro Tip: master the duplicated-loop version first; extract a helper only after both halves look correct.

Usage Tips

Small habits that keep hollow-diamond code clean.

  1. 1. Start Lower at rows - 1

    Starting at rows duplicates the waist.

  2. 2. Keep k Starting at 2

    Preserves single apex/tip stars on i == 1 rows.

  3. 3. Prefer TryParse

    Avoid crashes when the user types letters instead of a number.

  4. 4. Always Print Spaces

    Skipping the else branch collapses columns and ruins the diamond.

  5. 5. Dry-Run One Small n

    Trace rows = 4 (7 lines) before larger demos.

Pro Tip: if two identical widest rows appear in the middle, you almost certainly started the lower loop at rows.

Common Pitfalls

Mistakes that commonly break hollow diamonds.

  1. 1. Starting Lower Half at rows

    Duplicates the widest row in the middle.

    → Use for (i = rows - 1; i >= 1; i--).

  2. 2. Mixing Filled Logic Into Hollow Legs

    i != j && i != k does not magically fill the diamond.

    → For a solid diamond, use Program 10’s space/star formulas.

  3. 3. Omitting the else Space Branch

    Columns collapse; the outline becomes a smear.

    → Always print " " when the equality fails.

  4. 4. Dropping Trailing Spaces

    Right-side padding keeps width 2n-1; trimming breaks alignment.

    → Let both inner loops finish every row.

  5. 5. Blind Convert.ToInt32

    Letters or empty input throw FormatException.

    → Prefer int.TryParse and re-prompt on failure.

Edge Cases

Check these inputs before calling the solution done.

rows = 1

Single star

Upper prints one apex; lower (i = 0) never runs — one line total.

rows = 0

Empty pattern

Both outer loops skip — print nothing or show a message.

Negative

rows < 0

Treat as invalid; re-prompt instead of silent empty output.

Large n

Tall & wide

2n-1 lines and width — may wrap on tiny terminals.

Bad input

Non-numeric ReadLine

Convert.ToInt32 throws — use TryParse.

Waist

i == rows once

Only the upper loop should print the widest row.

🎯 Practice Problems

Try these variations to lock in the pattern.

1. Break then fix the waist

  • Start lower at rows, see the double line
  • Restore rows - 1

2. Print halves alone

  • Comment out lower → Program 7
  • Comment out upper → Program 8 shape

3. Extract PrintRow

  • Refactor to a helper like Example 3
  • Confirm output unchanged

4. Move to filled diamond

  • Replace outline legs with space + 2*i-1 stars
  • Match Program 10

Notes

  • Line count = width. Both equal 2 * rows - 1 for this construction.
  • rows is half-height to the waist, not the total printed line count.
  • Validate rows > 0 for interactive programs; rows = 1 prints a single star.
  • Next: Program 10 fills the diamond with solid star runs instead of an outline.

Quick Takeaway: print Program 7, then Program 8 from rows - 1 — that is the hollow diamond.

⏱️ Time and Space Complexity

ProgramTimeExtra space
Two outer loops (Examples 1–2)O(rows²)O(1)
Helper + ternary (Example 3)O(rows²)O(1)

About 2n - 1 lines, each with Θ(n) cell visits across left + right blocks.

Wrap Up

🎉 Conclusion

The hollow diamond is composition: Program 7’s inverted V plus Program 8’s V from rows - 1, sharing the same diagonal legs. Skip the duplicate waist, and the outline closes cleanly — then move on to a filled diamond if you want solid stars.

Practice the three examples above, then continue to the filled diamond.

Upper then lower, waist once, width = 2n−1 — keep the shared legs, and validate row counts when reading input.

💡 Best Practices

✅ Do

  • Explain “Program 7 then Program 8 from rows - 1” before coding
  • Keep identical j/k bodies on both halves
  • Print spaces whenever the equality fails
  • State total lines as 2 * rows - 1
  • Prefer int.TryParse for interactive demos

❌ Don’t

  • Start the lower loop at i == rows
  • Expect i != j alone to fill the diamond
  • Skip spaces so columns collapse
  • Ignore bad console input in user-facing demos
  • Skip the rows = 1 single-star edge case

Key Takeaways

Knowledge Unlocked

Five things to remember about the hollow diamond

Print the outline the beginner-friendly way.

5
Core concepts
02

Upper

i = 1..rows

Prog 7
03

Lower

i = rows-1..1

Prog 8
1 04

Waist

Print once

Seam
O 05

Complexity

O(n²) time

Analysis

❓ Frequently Asked Questions

Two sequential outer loops share the same inner structure. The first runs i from 1 to rows (inverted hollow V, upper half). The second runs i from rows minus 1 down to 1 (V-shaped hollow, 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. If the second part also started at i equals rows, that row would appear twice. Starting at rows minus 1 mirrors the upper half without duplicating the middle line.
Yes, by mapping loop index to 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.
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 space and 2*i-1 star runs.
Yes. Console.Write(i == j ? "*" : " ") and the same for k — same loops on both halves.
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 loop plus Program 8’s loop with the duplicate middle row removed by starting the second phase at rows - 1. Total printed lines = 2 * rows - 1.

Continue to 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