Back to LeetCode Series

LeetCode #6: Zigzag Conversion

Convert a string into a zigzag pattern across rows, then read line-by-line.

Difficulty: MediumPattern: String, SimulationTime: 7 min read

What is the Zigzag Pattern?

Imagine writing a string in a zigzag (or rail fence) pattern across a fixed number of rows:

  • Go down until you reach the bottom row
  • Then go diagonally up until you hit the top
  • Repeat until the string ends
  • Finally, read each row left to right to get the result
Example: "PAYPALISHIRING", 3 rows
P A H N
A P L S I I G
Y I R
→ Read row-by-row: PAHNAPLSIIGYIR

The Problem

Write the string in a zigzag pattern on a given number of rows, then return the characters read row by row.

Examples

Input: "PAYPALISHIRING", numRows=3

P A H N
A P L S I I G
Y I R

Output: "PAHNAPLSIIGYIR"  (P A H N A P L S I I G Y I R)

Input: "PAYPALISHIRING", numRows=4

P I N
A L S I G
Y A H R
P I

Output: "PINALSIGYAHRPI"  (P I N A L S I G Y A H R P I)

Input: "A", numRows=1

A

Output: "A"  (Single row → no change)

Approach: Simulate the Pattern

We can simulate the zigzag by:

  1. Create an array of numRows strings
  2. Traverse the input string and place each character in the correct row
  3. Use a direction flag to switch between moving down and up
  4. Concatenate all rows at the end
js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
function convert(s, numRows) {
 // If there's only one row, the string is already in the "zigzag" format, so we can return it as is.
  if(numRows ===1 ) return s;

    // create an array of strings, where each element will represent a row in the zigzag pattern
    // the size of the array is equal to the number of rows
    const rows = new Array(numRows).fill('');
    console.log(rows)

    // variable to keep track of current row we are adding characters to
    let currentRow = 0;

    // boolean flag to determine direction
    let goingDown = false;

    for(const char of s){
      console.log(rows)
        rows[currentRow] += char;

        // check if we have reached the top or bootom row
        // if we are at top row or bottom row (numRows -1)
        // we need to reverse our direction
        if(currentRow === 0 || currentRow === numRows-1){
            goingDown = !goingDown;
        }

        // move to the next row based on the direction
        // if going down increment currentRow
        // if goind up  decrement currentRow

        currentRow += goingDown ? 1 : -1
    }

    // finally join the strings in the rows together to form the final result
    return rows.join('')

}

O(n) time — each character visited once
O(n) space — for storing rows

Step-by-Step: "PAYPALISHIRING", 3 Rows

P → row 0 → ["P", "", ""]
A → row 1 → ["P", "A", ""]
Y → row 2 → ["P", "A", "Y"] → hit bottom → turn up
P → row 1 → ["P", "AP", "Y"]
A → row 0 → ["PA", "AP", "Y"] → hit top → turn down
... continue ...

At the end: ["PAHN", "APLSIIG", "YIR"] → join → "PAHNAPLSIIGYIR"

Zigzag Pattern Animator

Watch how characters flow into rows

300ms
[empty]
[empty]
[empty]
Final Output:
Step 0 / 14
Ready to start

🌍 Real-World Applications

The zigzag (or "rail fence") pattern isn't just a coding puzzle — it has real uses.

🔐 Cryptography: Rail Fence Cipher

One of the oldest ciphers — used in ancient times to encrypt messages by writing them in zigzag and reading row-wise. Your convert() function is literally an encryption tool!

📡 Networking: Data Interleaving

In communication systems, data is sometimes split across channels in a zigzag pattern to reduce burst errors. This helps with error correction and signal recovery.

🎵 Audio Processing: Sample Distribution

Some audio algorithms distribute samples across buffers in a pattern to avoid resonance or clipping. Zigzag-like distribution helps balance load.

🎮 Game Development

Pathfinding, text effects, or enemy movement patterns can use zigzag logic. Think of a snake moving across the screen or a scrolling background effect.

💡 Fun Fact: The rail fence cipher was used during the American Civil War to send secret messages. Now we have implemented it in JavaScript!

Summary

This problem teaches how to simulate a visual pattern using simple logic: track position, change direction at boundaries, and build incrementally.

It’s a great example of how string problems can be spatial — and perfect for interactive visualizations.

View All Challenges