Inverted V-Shaped Hollow Star Pattern in JavaScript
Beginner
7 min read
Updated: Sep 2026
3 programs
Live preview
Definition
What Is This Pattern?
An inverted V-shaped hollow pattern prints only the outline of an upside-down V: a single apex on row 1, then two stars that drift farther apart on each later row.
Remember
Rule: star when i === j (left) or i === k (right); else space
*
* *
* *
* *
* * ← 5 rows (width 9)
Unlike the filled inverted pyramid in Program 6, most cells are spaces. This outline is also the upper half of the hollow diamond — flip the outer loop in Program 8 to get the matching upright V.
Approach
How to Solve It
Two ways to emit the same outline — start with if/else legs, then optionally shorten with a ternary.
Method
Idea
Best for
If/else legs
Left j and right k loops; star when indices match
Learning, interviews, exams
Ternary ? :
Same bounds; one-line star-vs-space choice
Shorter demos once conditions click
Pseudocode
Pseudocode
for i from 1 to rows:
line = ""
for j from rows down to 1:
line += "*" if i === j else " "
for k from 2 to rows:
line += "*" if i === k else " "
print line
Change the height and the hollow inverted V updates instantly — including width and star count.
Whole numbers from 1 to 14. Each line is 2 * rows - 1 characters wide.
Live result5 rows · 9 stars
*
* *
* *
* *
* *
Trace
Worked Walkthrough — rows = 4
Trace where each star lands for every outer-loop value of i (line width = 7).
i
Left star (j)
Right star (k)
Stars
Printed row
1
j === 1
none (k starts at 2)
1
*
2
j === 2
k === 2
2
* *
3
j === 3
k === 3
2
* *
4
j === 4
k === 4
2
* *
Row 1 is the only single-star line — that is why the right loop must not start at k = 1. Total stars: 1 + 2 + 2 + 2 = 7 = 2×4 - 1.
Code
JavaScript Programs
Three complete programs: classic if/else, prompt input, and a ternary shortcut. Use View Output to reveal sample results.
Example 1 — Fixed rows = 5
Hard-coded height — left loop j = rows..1, right loop k = 2..rows, star when indices match.
JavaScript
let rows = 5;
for (let i = 1; i <= rows; i++) {
let line = "";
for (let j = rows; j >= 1; j--) {
if (i === j) {
line += "*";
} else {
line += " ";
}
}
for (let k = 2; k <= rows; k++) {
if (i === k) {
line += "*";
} else {
line += " ";
}
}
console.log(line);
}
Output
*
* *
* *
* *
* *
How It Works
1. Set height.rows = 5 means five outline lines (width 9).
2. Outer loop picks the row.i runs from 1 (apex) to rows (widest gap). Start a fresh line = "" each time.
3. Left leg.j counts from rows down to 1; append * only when i === j.
4. Right leg, then print.k runs from 2 to rows with the same match rule, then console.log(line).
When i = 1 only the left loop appends a star; when i = 5 stars land at both outer columns.
Example 2 — User Input Version
Read the height at runtime with prompt. Prefer validating with Number.isFinite (shown in the tip below).
JavaScript
let rows = parseInt(prompt("Enter the number of rows:"), 10);
for (let i = 1; i <= rows; i++) {
let line = "";
for (let j = rows; j >= 1; j--) {
if (i === j) {
line += "*";
} else {
line += " ";
}
}
for (let k = 2; k <= rows; k++) {
if (i === k) {
line += "*";
} else {
line += " ";
}
}
console.log(line);
}
Output (when user enters 4)
*
* *
* *
* *
How It Works
1. Prompt and parse. Ask for a row count, then convert with parseInt(..., 10).
2. Same left/right core. Only the source of rows changes — the leg logic matches Example 1.
3. Safer input tip. Bare parseInt yields NaN on letters or Cancel. Prefer:
Safer input
let rows = parseInt(prompt("Enter the number of rows:"), 10);
if (!Number.isFinite(rows) || rows < 1) {
console.log("Enter a positive whole number.");
} else {
// run the pattern loops here
}
Example 3 — Ternary ? : Form
Keep both loops; compress the star-vs-space choice into one expression each.
JavaScript
let rows = 5;
for (let i = 1; i <= rows; i++) {
let line = "";
for (let j = rows; j >= 1; j--) {
line += (i === j) ? "*" : " ";
}
for (let k = 2; k <= rows; k++) {
line += (i === k) ? "*" : " ";
}
console.log(line);
}
Output
*
* *
* *
* *
* *
How It Works
1. Same outer loop. Still walk i from 1 to rows.
2. Same bounds. Left j still counts down; right k still starts at 2.
3. Shorter append.(i === j) ? "*" : " " replaces the multi-line if/else — same decision, less code.
Learn the if/else version first (Examples 1–2) so you can explain the branch in an interview; treat this as a polish shortcut afterward.
Edge Cases & Pitfalls
Check these before calling the solution done.
k = 1
Duplicate apex
Starting the right loop at k = 1 prints two stars on row 1. Keep k = 2.
j ascending
Mirrored left leg
The left loop must count j from rows down to 1. Ascending j flips the left diagonal.
console.log inside
Broken outline
If console.log is inside either inner loop, each cell lands on its own line. Use line += for cells; log only after both loops.
rows = 1
Single apex
Output is just * — right loop never runs. A good sanity check.
rows ≤ 0
Empty output
Outer loop never runs. Validate before looping for interactive programs.
Bad prompt
Guard against NaN
Cancel or letters yield NaN — check Number.isFinite(rows) before looping.
Analysis
Time and Space Complexity
Program
Time
Extra space
If/else legs (Examples 1–2)
O(rows²)
O(rows) for the line string
Ternary form (Example 3)
O(rows²)
O(rows) for the line string
About n rows × 2n - 1 characters built per row — still quadratic in n. Total stars = 2n - 1 (one apex + two per later row).
Remember
Key Takeaways
Rule: append * only when i === j (left) or i === k (right).
Two legs: left j counts down; right k starts at 2.
Break the row: call console.log only after both inner loops.
Complexity:O(n²) time; O(n) for the row string.
One line: for each row i, append a star only when the left or right index matches i — start the right loop at 2.
Frequently Asked Questions
The outer loop runs i from 1 to rows. For each row, the left loop runs j from rows down to 1 and appends a star only when i equals j. The right loop runs k from 2 to rows and appends a star only when i equals k. Every other cell is a space.
Printing columns from high j to low j places the star for row i when i equals j. As i grows, that match moves leftward in the left block, forming the descending left leg.
On row 1 the left loop already prints the apex at j equals 1. Starting k at 1 would print a second star on that row. Starting at 2 avoids duplicating the tip.
line += stays on the same row with no newline between characters. console.log(line) ends the row after both inner loops finish.
Each line has width 2 * rows - 1: left block length rows, right block length rows - 1.
Program 8 uses the same inner loops but counts the outer loop from rows down to 1, so the wide row prints first and the legs meet at a bottom vertex.
O(n²) for n rows. Each row runs Theta(n) iterations across the two inner loops.
Use parseInt(prompt(...), 10) and check Number.isFinite(rows) && rows >= 1 so bad input does not produce NaN rows.
🤔
Did you know?
This hollow inverted V is the upper half of the hollow diamond. Starting the right loop at k = 2 is deliberate: on row 1 the left loop already prints the apex, so k = 1 would duplicate that star.