Skip to main content

Zigzag Grid Traversal With Skip | Leetcode : 3417 | Simple and Easy Explanation

Zigzag traversal is a fascinating grid-related problem that combines traversal logic and pattern handling. In this blog, we'll explore "3417. Zigzag Grid Traversal With Skip" from LeetCode, breaking down the problem, discussing multiple approaches, and understanding their nuances. By the end, you'll feel confident tackling similar problems with ease.

Problem Description

You are given an m x n grid of positive integers. Your task is to traverse the grid in a zigzag pattern while skipping every alternate cell. The zigzag pattern is defined as follows:

  1. Start at the top-left cell (0, 0).

  2. Move right within a row until the end of the row is reached.

  3. Drop down to the next row, then traverse left until the beginning of the row is reached.

  4. Repeat the above steps for all rows.

You must skip every alternate cell while traversing the grid.

Input and Output

  • Input: A 2D grid grid of positive integers.

  • Output: An array of integers containing the values of the visited cells in order.

Examples

Example 1:

Input: grid = [[1, 2], [3, 4]]
Output: [1, 4]

Example 2:

Input: grid = [[2, 1], [2, 1], [2, 1]]
Output: [2, 1, 2]

Example 3:

Input: grid = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Output: [1, 3, 5, 7, 9]

Constraints

  • 2 ≤ n == grid.length ≤ 50

  • 2 ≤ m == grid[i].length ≤ 50

  • 1 ≤ grid[i][j] ≤ 2500


Observations and Insights

  1. Zigzag Traversal:

    • Even-indexed rows (“row 0, 2, ...”) traverse from left to right.

    • Odd-indexed rows (“row 1, 3, ...”) traverse from right to left.

  2. Skipping Alternate Cells:

    • Use a boolean variable or logic to skip every second cell across the traversal, not just within a single row but across rows.

  3. Dimensions and Constraints:

    • The grid size is relatively small, making solutions feasible.


Approach 1: Brute Force Traversal

This approach implements the zigzag traversal with a straightforward row-by-row logic. A flag (skip) is used to determine whether to skip the current cell. The skipping condition carries over between rows to ensure consistent alternation.

Implementation (C++)

class Solution
{
public:
    vector<int> zigzagTraversal(vector<vector<int>> &grid)
    {
        int rows = grid.size();
        int cols = grid[0].size();
        vector<int> result;

        bool skip = false; // Whether to skip the next cell

        for (int i = 0; i < rows; i++)
        {
            if (i % 2 == 0)
            {
                // Traverse left to right
                for (int j = 0; j < cols; j++)
                {
                    if (!skip)
                        result.push_back(grid[i][j]);
                    skip = !skip;
                }
            }
            else
            {
                // Traverse right to left
                for (int j = cols - 1; j >= 0; j--)
                {
                    if (!skip)
                        result.push_back(grid[i][j]);
                    skip = !skip;
                }
            }
        }

        return result;
    }
};

Walkthrough for Example 3

  • Grid: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

  • Row 0: Visit 1, skip 2, visit 3.

  • Row 1: Skip 6, visit 5, skip 4.

  • Row 2: Visit 7, skip 8, visit 9.

  • Result: [1, 3, 5, 7, 9]


Complexity

  • Time Complexity: O(row * col) , as each cell is visited once.

  • Space Complexity: O(1), excluding the result vector.



Approach 2: Optimized Traversal with Cleaner Logic

To further optimize and simplify the traversal, we dynamically determine the start, end, and step size for each row based on its parity (even/odd). This avoids conditional checks inside the loops.

Implementation (C++)

class Solution
{
public:
    vector<int> zigzagTraversal(vector<vector<int>> &grid)
    {
        int rows = grid.size();
        int cols = grid[0].size();
        vector<int> result;
        bool skip = false;

        for (int i = 0; i < rows; i++)
        {
            int start = (i % 2 == 0) ? 0 : cols - 1;
            int end = (i % 2 == 0) ? cols : -1;
            int step = (i % 2 == 0) ? 1 : -1;

            for (int j = start; j != end; j += step)
            {
                if (!skip)
                    result.push_back(grid[i][j]);
                skip = !skip;
            }
        }

        return result;
    }
};

Key Changes

  1. Dynamic Ranges:

    • For even rows, traverse from 0 to cols - 1 with step 1.

    • For odd rows, traverse from cols - 1 to 0 with step -1.

  2. Simplified Loop Logic:

    • Eliminated redundant conditions inside the loops.

Complexity

  • Time Complexity: O(row * col), as each cell is visited once.

  • Space Complexity: O(1), excluding the result vector.



Tackling Similar Problems

When faced with traversal-based grid problems:

  1. Understand the Pattern:

    • Is it row-wise, column-wise, or diagonal?

    • Does the traversal alternate or follow a strict sequence?

  2. Handle Special Conditions:

    • Skipping cells, wrapping around, or conditional visiting.

  3. Optimize with Ranges:

    • Dynamically determine the start, end, and step sizes for loops.

    • Avoid unnecessary condition checks inside nested loops.

  4. Test Edge Cases:

    • Minimal grid sizes.

    • Skipping logic at boundaries.


The Zigzag Grid Traversal problem is an excellent exercise for building traversal skills and learning how to handle alternating patterns. By combining simple logic with efficient looping, we can solve the problem cleanly and confidently. If you found this post helpful, don’t forget to share it with your peers and keep practicing similar problems to solidify your understanding.

Popular posts from this blog

Maximum Difference Between Even and Odd Frequency | LeetCode

We are given a string consisting of lowercase English letters. Our task is to find the maximum difference between the frequency of two characters in the string such that: One of the characters has an even frequency . The other character has an odd frequency . The difference is calculated as:  odd_frequency - even_frequency We need to return the maximum possible difference between the odd and even frequencies. Example Walkthrough Let's take a couple of examples to better understand the problem: Example 1: Input:  s = "aaaaabbc" Frequencies: 'a' → 5 (odd) 'b' → 2 (even) 'c' → 1 (odd) Here, the maximum odd frequency is 5 (for 'a') and the maximum even frequency is 2 (for 'b'). Therefore, the result is: maxOdd - maxEven = 5 - 2 = 3 Example 2: Input:  s = "abcabcab" Frequencies: 'a' → 3 (odd) 'b' → 2 (even) 'c' → 2 (even) The maximum odd frequency is 3 (for 'a') and the maximum even fr...

Top 10 Beginner-Friendly LeetCode Questions and Their Solutions

If you're new to solving coding problems on LeetCode, it can feel overwhelming. Where do you start? Which problems are suitable for beginners? Don’t worry! In this blog post, I’ll guide you through   10 beginner-friendly LeetCode questions   that are perfect for getting started on your coding journey. These problems will help you build confidence, improve your problem-solving skills, and lay a solid foundation in data structures and algorithms. Why Start with Beginner-Friendly Problems? Before diving into advanced topics like dynamic programming or graph theory, it’s essential to: Build a strong foundation in basic programming concepts. Understand how to approach a coding problem methodically. Gain familiarity with LeetCode’s platform and its problem structure. The following problems are simple yet impactful, designed to introduce you to common techniques like loops, arrays, strings, and basic math operations. 10 Beginner-Friendly LeetCode Problems 1.  Two Sum (Easy) Prob...

Count Mentions Per User | Leetcode | Problem Explanation and Solution Approaches

Tracking mentions in messages is a common task in communication-based applications. This blog post breaks down a complex problem, "Count Mentions Per User," and walks through how to solve it efficiently with a clear understanding of all rules and constraints. Problem Statement You are given: An integer numberOfUsers representing the total number of users. An array events where each element is of size n x 3 and describes either a "MESSAGE" or an "OFFLINE" event. Each event can be one of the following types: MESSAGE Event : ["MESSAGE", "timestamp", "mentions_string"] Indicates that users are mentioned in a message at a specific timestamp. The mentions_string can contain: id<number> : Mentions a specific user (e.g., id0 , id1 ). ALL : Mentions all users (online or offline). HERE : Mentions only users who are online at the time. OFFLINE Event : ["OFFLINE", "timestamp", "id<number>"] In...