Zigzag Conversion · Optimal Solution

Bounce between rows, read left to right.

Imagine writing text diagonally downward, bouncing off the bottom row, rising back to the top, and repeating — like a ball in a zigzag pinball machine. Once every character is placed, read each row from left to right and concatenate. No matrix needed: numRows string buckets and a direction flag capture the full pattern in O(n) time.


Interactive

Watch the zigzag form


Concept

Three ideas behind the bounce

The zigzag pattern emerges from a simple row counter that oscillates between 0 and numRows − 1. No coordinates, no modular arithmetic — just a direction flag.

row buckets

Create numRows empty strings. Each character is appended to the bucket matching its current row. At the end, concatenate all buckets top-to-bottom for the answer.

direction toggle

A boolean movingDown controls the bounce. When the pointer hits row 0 it flips to down; when it hits the last row it flips to up. The pointer then advances by +1 or −1.

linear scan

Each character is visited exactly once and appended in O(1). The entire string is processed in a single pass — no extra matrix, no index formulas, just a bouncing pointer.


Algorithm

Place, bounce, read

  1. Guard: single row

    If numRows == 1, the zigzag is flat — return the input unchanged.

  2. Walk and bounce

    Start at row 0, direction down. For each character: append it to rowBuckets[currentRow]. If currentRow reaches the top or bottom, reverse direction. Then advance the row pointer.

  3. Concatenate rows

    Join all row buckets from row 0 through row numRows − 1. The result is the zigzag-encoded string.


Edge Cases

When the zigzag simplifies

numRows == 1

No bouncing occurs — every character lands in the same row. The output equals the input. The algorithm short-circuits before allocating any buckets.

numRows ≥ text length

The pointer descends but never bounces back. Each character occupies its own row, producing a straight vertical line. The output equals the input read top-to-bottom.

numRows == 2

The zigzag degenerates to alternating rows: even-indexed characters in row 0, odd-indexed in row 1. The period is just 2, the simplest non-trivial case.